post-for-me 0.1.0.pre.alpha.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 (158) hide show
  1. checksums.yaml +7 -0
  2. data/.ignore +2 -0
  3. data/CHANGELOG.md +32 -0
  4. data/README.md +265 -0
  5. data/SECURITY.md +27 -0
  6. data/lib/post_for_me/client.rb +86 -0
  7. data/lib/post_for_me/errors.rb +214 -0
  8. data/lib/post_for_me/file_part.rb +55 -0
  9. data/lib/post_for_me/internal/transport/base_client.rb +563 -0
  10. data/lib/post_for_me/internal/transport/pooled_net_requester.rb +209 -0
  11. data/lib/post_for_me/internal/type/array_of.rb +168 -0
  12. data/lib/post_for_me/internal/type/base_model.rb +537 -0
  13. data/lib/post_for_me/internal/type/base_page.rb +55 -0
  14. data/lib/post_for_me/internal/type/boolean.rb +77 -0
  15. data/lib/post_for_me/internal/type/converter.rb +327 -0
  16. data/lib/post_for_me/internal/type/enum.rb +131 -0
  17. data/lib/post_for_me/internal/type/file_input.rb +108 -0
  18. data/lib/post_for_me/internal/type/hash_of.rb +188 -0
  19. data/lib/post_for_me/internal/type/request_parameters.rb +42 -0
  20. data/lib/post_for_me/internal/type/union.rb +237 -0
  21. data/lib/post_for_me/internal/type/unknown.rb +81 -0
  22. data/lib/post_for_me/internal/util.rb +914 -0
  23. data/lib/post_for_me/internal.rb +20 -0
  24. data/lib/post_for_me/models/create_social_post.rb +558 -0
  25. data/lib/post_for_me/models/media_create_upload_url_params.rb +14 -0
  26. data/lib/post_for_me/models/media_create_upload_url_response.rb +25 -0
  27. data/lib/post_for_me/models/social_account.rb +110 -0
  28. data/lib/post_for_me/models/social_account_create_auth_url_params.rb +109 -0
  29. data/lib/post_for_me/models/social_account_create_auth_url_response.rb +25 -0
  30. data/lib/post_for_me/models/social_account_disconnect_params.rb +14 -0
  31. data/lib/post_for_me/models/social_account_disconnect_response.rb +109 -0
  32. data/lib/post_for_me/models/social_account_list_params.rb +69 -0
  33. data/lib/post_for_me/models/social_account_list_response.rb +58 -0
  34. data/lib/post_for_me/models/social_account_retrieve_params.rb +14 -0
  35. data/lib/post_for_me/models/social_account_update_params.rb +30 -0
  36. data/lib/post_for_me/models/social_post.rb +114 -0
  37. data/lib/post_for_me/models/social_post_create_params.rb +14 -0
  38. data/lib/post_for_me/models/social_post_delete_params.rb +14 -0
  39. data/lib/post_for_me/models/social_post_delete_response.rb +17 -0
  40. data/lib/post_for_me/models/social_post_list_params.rb +87 -0
  41. data/lib/post_for_me/models/social_post_list_response.rb +58 -0
  42. data/lib/post_for_me/models/social_post_result.rb +87 -0
  43. data/lib/post_for_me/models/social_post_result_list_params.rb +51 -0
  44. data/lib/post_for_me/models/social_post_result_list_response.rb +58 -0
  45. data/lib/post_for_me/models/social_post_result_retrieve_params.rb +14 -0
  46. data/lib/post_for_me/models/social_post_retrieve_params.rb +14 -0
  47. data/lib/post_for_me/models/social_post_update_params.rb +14 -0
  48. data/lib/post_for_me/models/tiktok_configuration.rb +88 -0
  49. data/lib/post_for_me/models.rb +77 -0
  50. data/lib/post_for_me/request_options.rb +77 -0
  51. data/lib/post_for_me/resources/media.rb +94 -0
  52. data/lib/post_for_me/resources/social_accounts.rb +143 -0
  53. data/lib/post_for_me/resources/social_post_results.rb +65 -0
  54. data/lib/post_for_me/resources/social_posts.rb +164 -0
  55. data/lib/post_for_me/version.rb +5 -0
  56. data/lib/post_for_me.rb +82 -0
  57. data/manifest.yaml +15 -0
  58. data/rbi/post_for_me/client.rbi +58 -0
  59. data/rbi/post_for_me/errors.rbi +178 -0
  60. data/rbi/post_for_me/file_part.rbi +37 -0
  61. data/rbi/post_for_me/internal/transport/base_client.rbi +294 -0
  62. data/rbi/post_for_me/internal/transport/pooled_net_requester.rbi +79 -0
  63. data/rbi/post_for_me/internal/type/array_of.rbi +104 -0
  64. data/rbi/post_for_me/internal/type/base_model.rbi +304 -0
  65. data/rbi/post_for_me/internal/type/base_page.rbi +42 -0
  66. data/rbi/post_for_me/internal/type/boolean.rbi +58 -0
  67. data/rbi/post_for_me/internal/type/converter.rbi +216 -0
  68. data/rbi/post_for_me/internal/type/enum.rbi +82 -0
  69. data/rbi/post_for_me/internal/type/file_input.rbi +59 -0
  70. data/rbi/post_for_me/internal/type/hash_of.rbi +104 -0
  71. data/rbi/post_for_me/internal/type/request_parameters.rbi +29 -0
  72. data/rbi/post_for_me/internal/type/union.rbi +128 -0
  73. data/rbi/post_for_me/internal/type/unknown.rbi +58 -0
  74. data/rbi/post_for_me/internal/util.rbi +487 -0
  75. data/rbi/post_for_me/internal.rbi +18 -0
  76. data/rbi/post_for_me/models/create_social_post.rbi +1128 -0
  77. data/rbi/post_for_me/models/media_create_upload_url_params.rbi +30 -0
  78. data/rbi/post_for_me/models/media_create_upload_url_response.rbi +38 -0
  79. data/rbi/post_for_me/models/social_account.rbi +139 -0
  80. data/rbi/post_for_me/models/social_account_create_auth_url_params.rbi +260 -0
  81. data/rbi/post_for_me/models/social_account_create_auth_url_response.rbi +36 -0
  82. data/rbi/post_for_me/models/social_account_disconnect_params.rbi +30 -0
  83. data/rbi/post_for_me/models/social_account_disconnect_response.rbi +156 -0
  84. data/rbi/post_for_me/models/social_account_list_params.rbi +112 -0
  85. data/rbi/post_for_me/models/social_account_list_response.rbi +107 -0
  86. data/rbi/post_for_me/models/social_account_retrieve_params.rbi +30 -0
  87. data/rbi/post_for_me/models/social_account_update_params.rbi +60 -0
  88. data/rbi/post_for_me/models/social_post.rbi +142 -0
  89. data/rbi/post_for_me/models/social_post_create_params.rbi +27 -0
  90. data/rbi/post_for_me/models/social_post_delete_params.rbi +27 -0
  91. data/rbi/post_for_me/models/social_post_delete_response.rbi +30 -0
  92. data/rbi/post_for_me/models/social_post_list_params.rbi +207 -0
  93. data/rbi/post_for_me/models/social_post_list_response.rbi +107 -0
  94. data/rbi/post_for_me/models/social_post_result.rbi +130 -0
  95. data/rbi/post_for_me/models/social_post_result_list_params.rbi +86 -0
  96. data/rbi/post_for_me/models/social_post_result_list_response.rbi +107 -0
  97. data/rbi/post_for_me/models/social_post_result_retrieve_params.rbi +30 -0
  98. data/rbi/post_for_me/models/social_post_retrieve_params.rbi +30 -0
  99. data/rbi/post_for_me/models/social_post_update_params.rbi +27 -0
  100. data/rbi/post_for_me/models/tiktok_configuration.rbi +109 -0
  101. data/rbi/post_for_me/models.rbi +42 -0
  102. data/rbi/post_for_me/request_options.rbi +59 -0
  103. data/rbi/post_for_me/resources/media.rbi +83 -0
  104. data/rbi/post_for_me/resources/social_accounts.rbi +112 -0
  105. data/rbi/post_for_me/resources/social_post_results.rbi +51 -0
  106. data/rbi/post_for_me/resources/social_posts.rbi +160 -0
  107. data/rbi/post_for_me/version.rbi +5 -0
  108. data/sig/post_for_me/client.rbs +32 -0
  109. data/sig/post_for_me/errors.rbs +110 -0
  110. data/sig/post_for_me/file_part.rbs +21 -0
  111. data/sig/post_for_me/internal/transport/base_client.rbs +131 -0
  112. data/sig/post_for_me/internal/transport/pooled_net_requester.rbs +45 -0
  113. data/sig/post_for_me/internal/type/array_of.rbs +48 -0
  114. data/sig/post_for_me/internal/type/base_model.rbs +102 -0
  115. data/sig/post_for_me/internal/type/base_page.rbs +24 -0
  116. data/sig/post_for_me/internal/type/boolean.rbs +26 -0
  117. data/sig/post_for_me/internal/type/converter.rbs +79 -0
  118. data/sig/post_for_me/internal/type/enum.rbs +32 -0
  119. data/sig/post_for_me/internal/type/file_input.rbs +25 -0
  120. data/sig/post_for_me/internal/type/hash_of.rbs +48 -0
  121. data/sig/post_for_me/internal/type/request_parameters.rbs +19 -0
  122. data/sig/post_for_me/internal/type/union.rbs +52 -0
  123. data/sig/post_for_me/internal/type/unknown.rbs +26 -0
  124. data/sig/post_for_me/internal/util.rbs +185 -0
  125. data/sig/post_for_me/internal.rbs +9 -0
  126. data/sig/post_for_me/models/create_social_post.rbs +398 -0
  127. data/sig/post_for_me/models/media_create_upload_url_params.rbs +15 -0
  128. data/sig/post_for_me/models/media_create_upload_url_response.rbs +16 -0
  129. data/sig/post_for_me/models/social_account.rbs +81 -0
  130. data/sig/post_for_me/models/social_account_create_auth_url_params.rbs +105 -0
  131. data/sig/post_for_me/models/social_account_create_auth_url_response.rbs +16 -0
  132. data/sig/post_for_me/models/social_account_disconnect_params.rbs +15 -0
  133. data/sig/post_for_me/models/social_account_disconnect_response.rbs +80 -0
  134. data/sig/post_for_me/models/social_account_list_params.rbs +63 -0
  135. data/sig/post_for_me/models/social_account_list_response.rbs +51 -0
  136. data/sig/post_for_me/models/social_account_retrieve_params.rbs +15 -0
  137. data/sig/post_for_me/models/social_account_update_params.rbs +32 -0
  138. data/sig/post_for_me/models/social_post.rbs +83 -0
  139. data/sig/post_for_me/models/social_post_create_params.rbs +15 -0
  140. data/sig/post_for_me/models/social_post_delete_params.rbs +15 -0
  141. data/sig/post_for_me/models/social_post_delete_response.rbs +13 -0
  142. data/sig/post_for_me/models/social_post_list_params.rbs +100 -0
  143. data/sig/post_for_me/models/social_post_list_response.rbs +51 -0
  144. data/sig/post_for_me/models/social_post_result.rbs +66 -0
  145. data/sig/post_for_me/models/social_post_result_list_params.rbs +49 -0
  146. data/sig/post_for_me/models/social_post_result_list_response.rbs +51 -0
  147. data/sig/post_for_me/models/social_post_result_retrieve_params.rbs +15 -0
  148. data/sig/post_for_me/models/social_post_retrieve_params.rbs +15 -0
  149. data/sig/post_for_me/models/social_post_update_params.rbs +15 -0
  150. data/sig/post_for_me/models/tiktok_configuration.rbs +65 -0
  151. data/sig/post_for_me/models.rbs +37 -0
  152. data/sig/post_for_me/request_options.rbs +34 -0
  153. data/sig/post_for_me/resources/media.rbs +11 -0
  154. data/sig/post_for_me/resources/social_accounts.rbs +40 -0
  155. data/sig/post_for_me/resources/social_post_results.rbs +20 -0
  156. data/sig/post_for_me/resources/social_posts.rbs +51 -0
  157. data/sig/post_for_me/version.rbs +3 -0
  158. metadata +215 -0
@@ -0,0 +1,537 @@
1
+ # frozen_string_literal: true
2
+
3
+ module PostForMe
4
+ module Internal
5
+ module Type
6
+ # @abstract
7
+ class BaseModel
8
+ extend PostForMe::Internal::Type::Converter
9
+ extend PostForMe::Internal::Util::SorbetRuntimeSupport
10
+
11
+ class << self
12
+ # @api private
13
+ #
14
+ # Assumes superclass fields are totally defined before fields are accessed /
15
+ # defined on subclasses.
16
+ #
17
+ # @param child [Class<PostForMe::Internal::Type::BaseModel>]
18
+ def inherited(child)
19
+ super
20
+ child.known_fields.replace(known_fields.dup)
21
+ end
22
+
23
+ # @api private
24
+ #
25
+ # @return [Hash{Symbol=>Hash{Symbol=>Object}}]
26
+ def known_fields = @known_fields ||= {}
27
+
28
+ # @api private
29
+ #
30
+ # @return [Hash{Symbol=>Hash{Symbol=>Object}}]
31
+ def fields
32
+ known_fields.transform_values do |field|
33
+ {**field.except(:type_fn), type: field.fetch(:type_fn).call}
34
+ end
35
+ end
36
+
37
+ # @api private
38
+ #
39
+ # @param name_sym [Symbol]
40
+ #
41
+ # @param required [Boolean]
42
+ #
43
+ # @param type_info [Hash{Symbol=>Object}, Proc, PostForMe::Internal::Type::Converter, Class]
44
+ #
45
+ # @param spec [Hash{Symbol=>Object}] .
46
+ #
47
+ # @option spec [NilClass, TrueClass, FalseClass, Integer, Float, Symbol] :const
48
+ #
49
+ # @option spec [Proc] :enum
50
+ #
51
+ # @option spec [Proc] :union
52
+ #
53
+ # @option spec [Boolean] :"nil?"
54
+ private def add_field(name_sym, required:, type_info:, spec:)
55
+ meta = PostForMe::Internal::Type::Converter.meta_info(type_info, spec)
56
+ type_fn, info =
57
+ case type_info
58
+ in Proc | PostForMe::Internal::Type::Converter | Class
59
+ [PostForMe::Internal::Type::Converter.type_info({**spec, union: type_info}), spec]
60
+ in Hash
61
+ [PostForMe::Internal::Type::Converter.type_info(type_info), type_info]
62
+ end
63
+
64
+ setter = :"#{name_sym}="
65
+ api_name = info.fetch(:api_name, name_sym)
66
+ nilable = info.fetch(:nil?, false)
67
+ const = if required && !nilable
68
+ info.fetch(
69
+ :const,
70
+ PostForMe::Internal::OMIT
71
+ )
72
+ else
73
+ PostForMe::Internal::OMIT
74
+ end
75
+
76
+ [name_sym, setter].each { undef_method(_1) } if known_fields.key?(name_sym)
77
+
78
+ known_fields[name_sym] =
79
+ {
80
+ mode: @mode,
81
+ api_name: api_name,
82
+ required: required,
83
+ nilable: nilable,
84
+ const: const,
85
+ type_fn: type_fn,
86
+ meta: meta
87
+ }
88
+
89
+ define_method(setter) do |value|
90
+ target = type_fn.call
91
+ state = PostForMe::Internal::Type::Converter.new_coerce_state(translate_names: false)
92
+ coerced = PostForMe::Internal::Type::Converter.coerce(target, value, state: state)
93
+ status = @coerced.store(name_sym, state.fetch(:error) || true)
94
+ stored =
95
+ case [target, status]
96
+ in [PostForMe::Internal::Type::Converter | Symbol, true]
97
+ coerced
98
+ else
99
+ value
100
+ end
101
+ @data.store(name_sym, stored)
102
+ end
103
+
104
+ # rubocop:disable Style/CaseEquality
105
+ # rubocop:disable Metrics/BlockLength
106
+ define_method(name_sym) do
107
+ target = type_fn.call
108
+
109
+ case @coerced[name_sym]
110
+ in true | false if PostForMe::Internal::Type::Converter === target
111
+ @data.fetch(name_sym)
112
+ in ::StandardError => e
113
+ raise PostForMe::Errors::ConversionError.new(
114
+ on: self.class,
115
+ method: __method__,
116
+ target: target,
117
+ value: @data.fetch(name_sym),
118
+ cause: e
119
+ )
120
+ else
121
+ Kernel.then do
122
+ value = @data.fetch(name_sym) { const == PostForMe::Internal::OMIT ? nil : const }
123
+ state = PostForMe::Internal::Type::Converter.new_coerce_state(translate_names: false)
124
+ if (nilable || !required) && value.nil?
125
+ nil
126
+ else
127
+ PostForMe::Internal::Type::Converter.coerce(
128
+ target, value, state: state
129
+ )
130
+ end
131
+ rescue StandardError => e
132
+ raise PostForMe::Errors::ConversionError.new(
133
+ on: self.class,
134
+ method: __method__,
135
+ target: target,
136
+ value: value,
137
+ cause: e
138
+ )
139
+ end
140
+ end
141
+ end
142
+ # rubocop:enable Metrics/BlockLength
143
+ # rubocop:enable Style/CaseEquality
144
+ end
145
+
146
+ # @api private
147
+ #
148
+ # @param name_sym [Symbol]
149
+ #
150
+ # @param type_info [Hash{Symbol=>Object}, Proc, PostForMe::Internal::Type::Converter, Class]
151
+ #
152
+ # @param spec [Hash{Symbol=>Object}] .
153
+ #
154
+ # @option spec [NilClass, TrueClass, FalseClass, Integer, Float, Symbol] :const
155
+ #
156
+ # @option spec [Proc] :enum
157
+ #
158
+ # @option spec [Proc] :union
159
+ #
160
+ # @option spec [Boolean] :"nil?"
161
+ def required(name_sym, type_info, spec = {})
162
+ add_field(name_sym, required: true, type_info: type_info, spec: spec)
163
+ end
164
+
165
+ # @api private
166
+ #
167
+ # @param name_sym [Symbol]
168
+ #
169
+ # @param type_info [Hash{Symbol=>Object}, Proc, PostForMe::Internal::Type::Converter, Class]
170
+ #
171
+ # @param spec [Hash{Symbol=>Object}] .
172
+ #
173
+ # @option spec [NilClass, TrueClass, FalseClass, Integer, Float, Symbol] :const
174
+ #
175
+ # @option spec [Proc] :enum
176
+ #
177
+ # @option spec [Proc] :union
178
+ #
179
+ # @option spec [Boolean] :"nil?"
180
+ def optional(name_sym, type_info, spec = {})
181
+ add_field(name_sym, required: false, type_info: type_info, spec: spec)
182
+ end
183
+
184
+ # @api private
185
+ #
186
+ # `request_only` attributes not excluded from `.#coerce` when receiving responses
187
+ # even if well behaved servers should not send them
188
+ #
189
+ # @param blk [Proc]
190
+ private def request_only(&blk)
191
+ @mode = :dump
192
+ blk.call
193
+ ensure
194
+ @mode = nil
195
+ end
196
+
197
+ # @api private
198
+ #
199
+ # `response_only` attributes are omitted from `.#dump` when making requests
200
+ #
201
+ # @param blk [Proc]
202
+ private def response_only(&blk)
203
+ @mode = :coerce
204
+ blk.call
205
+ ensure
206
+ @mode = nil
207
+ end
208
+
209
+ # @api public
210
+ #
211
+ # @param other [Object]
212
+ #
213
+ # @return [Boolean]
214
+ def ==(other)
215
+ other.is_a?(Class) && other <= PostForMe::Internal::Type::BaseModel && other.fields == fields
216
+ end
217
+
218
+ # @api public
219
+ #
220
+ # @return [Integer]
221
+ def hash = fields.hash
222
+ end
223
+
224
+ # @api public
225
+ #
226
+ # @param other [Object]
227
+ #
228
+ # @return [Boolean]
229
+ def ==(other) = self.class == other.class && @data == other.to_h
230
+
231
+ # @api public
232
+ #
233
+ # @return [Integer]
234
+ def hash = [self.class, @data].hash
235
+
236
+ class << self
237
+ # @api private
238
+ #
239
+ # @param value [PostForMe::Internal::Type::BaseModel, Hash{Object=>Object}, Object]
240
+ #
241
+ # @param state [Hash{Symbol=>Object}] .
242
+ #
243
+ # @option state [Boolean] :translate_names
244
+ #
245
+ # @option state [Boolean] :strictness
246
+ #
247
+ # @option state [Hash{Symbol=>Object}] :exactness
248
+ #
249
+ # @option state [Class<StandardError>] :error
250
+ #
251
+ # @option state [Integer] :branched
252
+ #
253
+ # @return [self, Object]
254
+ def coerce(value, state:)
255
+ exactness = state.fetch(:exactness)
256
+
257
+ if value.is_a?(self)
258
+ exactness[:yes] += 1
259
+ return value
260
+ end
261
+
262
+ unless (val = PostForMe::Internal::Util.coerce_hash(value)).is_a?(Hash)
263
+ exactness[:no] += 1
264
+ state[:error] = TypeError.new("#{value.class} can't be coerced into #{Hash}")
265
+ return value
266
+ end
267
+ exactness[:yes] += 1
268
+
269
+ keys = val.keys.to_set
270
+ instance = new
271
+ data = instance.to_h
272
+ status = instance.instance_variable_get(:@coerced)
273
+
274
+ # rubocop:disable Metrics/BlockLength
275
+ fields.each do |name, field|
276
+ mode, required, target = field.fetch_values(:mode, :required, :type)
277
+ api_name, nilable, const = field.fetch_values(:api_name, :nilable, :const)
278
+ src_name = state.fetch(:translate_names) ? api_name : name
279
+
280
+ unless val.key?(src_name)
281
+ if required && mode != :dump && const == PostForMe::Internal::OMIT
282
+ exactness[nilable ? :maybe : :no] += 1
283
+ else
284
+ exactness[:yes] += 1
285
+ end
286
+ next
287
+ end
288
+
289
+ item = val.fetch(src_name)
290
+ keys.delete(src_name)
291
+
292
+ state[:error] = nil
293
+ converted =
294
+ if item.nil? && (nilable || !required)
295
+ exactness[nilable ? :yes : :maybe] += 1
296
+ nil
297
+ else
298
+ coerced = PostForMe::Internal::Type::Converter.coerce(target, item, state: state)
299
+ case target
300
+ in PostForMe::Internal::Type::Converter | Symbol
301
+ coerced
302
+ else
303
+ item
304
+ end
305
+ end
306
+
307
+ status.store(name, state.fetch(:error) || true)
308
+ data.store(name, converted)
309
+ end
310
+ # rubocop:enable Metrics/BlockLength
311
+
312
+ keys.each { data.store(_1, val.fetch(_1)) }
313
+ instance
314
+ end
315
+
316
+ # @api private
317
+ #
318
+ # @param value [self, Object]
319
+ #
320
+ # @param state [Hash{Symbol=>Object}] .
321
+ #
322
+ # @option state [Boolean] :can_retry
323
+ #
324
+ # @return [Hash{Object=>Object}, Object]
325
+ def dump(value, state:)
326
+ unless (coerced = PostForMe::Internal::Util.coerce_hash(value)).is_a?(Hash)
327
+ return super
328
+ end
329
+
330
+ acc = {}
331
+
332
+ coerced.each do |key, val|
333
+ name = key.is_a?(String) ? key.to_sym : key
334
+ case (field = known_fields[name])
335
+ in nil
336
+ acc.store(name, super(val, state: state))
337
+ else
338
+ api_name, mode, type_fn = field.fetch_values(:api_name, :mode, :type_fn)
339
+ case mode
340
+ in :coerce
341
+ next
342
+ else
343
+ target = type_fn.call
344
+ acc.store(api_name, PostForMe::Internal::Type::Converter.dump(target, val, state: state))
345
+ end
346
+ end
347
+ end
348
+
349
+ known_fields.each_value do |field|
350
+ api_name, mode, const = field.fetch_values(:api_name, :mode, :const)
351
+ next if mode == :coerce || acc.key?(api_name) || const == PostForMe::Internal::OMIT
352
+ acc.store(api_name, const)
353
+ end
354
+
355
+ acc
356
+ end
357
+
358
+ # @api private
359
+ #
360
+ # @return [Object]
361
+ def to_sorbet_type
362
+ self
363
+ end
364
+ end
365
+
366
+ class << self
367
+ # @api private
368
+ #
369
+ # @param model [PostForMe::Internal::Type::BaseModel]
370
+ # @param convert [Boolean]
371
+ #
372
+ # @return [Hash{Symbol=>Object}]
373
+ def recursively_to_h(model, convert:)
374
+ rec = ->(x) do
375
+ case x
376
+ in PostForMe::Internal::Type::BaseModel
377
+ if convert
378
+ fields = x.class.known_fields
379
+ x.to_h.to_h do |key, val|
380
+ [key, rec.call(fields.key?(key) ? x.public_send(key) : val)]
381
+ rescue PostForMe::Errors::ConversionError
382
+ [key, rec.call(val)]
383
+ end
384
+ else
385
+ rec.call(x.to_h)
386
+ end
387
+ in Hash
388
+ x.transform_values(&rec)
389
+ in Array
390
+ x.map(&rec)
391
+ else
392
+ x
393
+ end
394
+ end
395
+ rec.call(model)
396
+ end
397
+ end
398
+
399
+ # @api public
400
+ #
401
+ # Returns the raw value associated with the given key, if found. Otherwise, nil is
402
+ # returned.
403
+ #
404
+ # It is valid to lookup keys that are not in the API spec, for example to access
405
+ # undocumented features. This method does not parse response data into
406
+ # higher-level types. Lookup by anything other than a Symbol is an ArgumentError.
407
+ #
408
+ # @param key [Symbol]
409
+ #
410
+ # @return [Object, nil]
411
+ def [](key)
412
+ unless key.instance_of?(Symbol)
413
+ raise ArgumentError.new("Expected symbol key for lookup, got #{key.inspect}")
414
+ end
415
+
416
+ @data[key]
417
+ end
418
+
419
+ # @api public
420
+ #
421
+ # Returns a Hash of the data underlying this object. O(1)
422
+ #
423
+ # Keys are Symbols and values are the raw values from the response. The return
424
+ # value indicates which values were ever set on the object. i.e. there will be a
425
+ # key in this hash if they ever were, even if the set value was nil.
426
+ #
427
+ # This method is not recursive. The returned value is shared by the object, so it
428
+ # should not be mutated.
429
+ #
430
+ # @return [Hash{Symbol=>Object}]
431
+ def to_h = @data
432
+
433
+ alias_method :to_hash, :to_h
434
+
435
+ # @api public
436
+ #
437
+ # In addition to the behaviour of `#to_h`, this method will recursively call
438
+ # `#to_h` on nested models.
439
+ #
440
+ # @return [Hash{Symbol=>Object}]
441
+ def deep_to_h = self.class.recursively_to_h(@data, convert: false)
442
+
443
+ # @param keys [Array<Symbol>, nil]
444
+ #
445
+ # @return [Hash{Symbol=>Object}]
446
+ #
447
+ # @example
448
+ # # `media_create_upload_url_response` is a `PostForMe::Models::MediaCreateUploadURLResponse`
449
+ # media_create_upload_url_response => {
450
+ # media_url: media_url,
451
+ # upload_url: upload_url
452
+ # }
453
+ def deconstruct_keys(keys)
454
+ (keys || self.class.known_fields.keys)
455
+ .filter_map do |k|
456
+ unless self.class.known_fields.key?(k)
457
+ next
458
+ end
459
+
460
+ [k, public_send(k)]
461
+ end
462
+ .to_h
463
+ end
464
+
465
+ # @api public
466
+ #
467
+ # @param a [Object]
468
+ #
469
+ # @return [String]
470
+ def to_json(*a) = PostForMe::Internal::Type::Converter.dump(self.class, self).to_json(*a)
471
+
472
+ # @api public
473
+ #
474
+ # @param a [Object]
475
+ #
476
+ # @return [String]
477
+ def to_yaml(*a) = PostForMe::Internal::Type::Converter.dump(self.class, self).to_yaml(*a)
478
+
479
+ # Create a new instance of a model.
480
+ #
481
+ # @param data [Hash{Symbol=>Object}, self]
482
+ def initialize(data = {})
483
+ @data = {}
484
+ @coerced = {}
485
+ PostForMe::Internal::Util.coerce_hash!(data).each do
486
+ if self.class.known_fields.key?(_1)
487
+ public_send(:"#{_1}=", _2)
488
+ else
489
+ @data.store(_1, _2)
490
+ @coerced.store(_1, false)
491
+ end
492
+ end
493
+ end
494
+
495
+ class << self
496
+ # @api private
497
+ #
498
+ # @param depth [Integer]
499
+ #
500
+ # @return [String]
501
+ def inspect(depth: 0)
502
+ return super() if depth.positive?
503
+
504
+ depth = depth.succ
505
+ deferred = fields.transform_values do |field|
506
+ type, required, nilable = field.fetch_values(:type, :required, :nilable)
507
+ inspected = [
508
+ PostForMe::Internal::Type::Converter.inspect(type, depth: depth),
509
+ !required || nilable ? "nil" : nil
510
+ ].compact.join(" | ")
511
+ -> { inspected }.tap { _1.define_singleton_method(:inspect) { call } }
512
+ end
513
+
514
+ "#{name}[#{deferred.inspect}]"
515
+ end
516
+ end
517
+
518
+ # @api public
519
+ #
520
+ # @return [String]
521
+ def to_s = deep_to_h.to_s
522
+
523
+ # @api private
524
+ #
525
+ # @return [String]
526
+ def inspect
527
+ converted = self.class.recursively_to_h(self, convert: true)
528
+ "#<#{self.class}:0x#{object_id.to_s(16)} #{converted}>"
529
+ end
530
+
531
+ define_sorbet_constant!(:KnownField) do
532
+ T.type_alias { {mode: T.nilable(Symbol), required: T::Boolean, nilable: T::Boolean} }
533
+ end
534
+ end
535
+ end
536
+ end
537
+ end
@@ -0,0 +1,55 @@
1
+ # frozen_string_literal: true
2
+
3
+ module PostForMe
4
+ module Internal
5
+ module Type
6
+ # @api private
7
+ #
8
+ # @generic Elem
9
+ #
10
+ # This module provides a base implementation for paginated responses in the SDK.
11
+ module BasePage
12
+ # rubocop:disable Lint/UnusedMethodArgument
13
+
14
+ # @api public
15
+ #
16
+ # @return [Boolean]
17
+ def next_page? = (raise NotImplementedError)
18
+
19
+ # @api public
20
+ #
21
+ # @raise [PostForMe::Errors::APIError]
22
+ # @return [self]
23
+ def next_page = (raise NotImplementedError)
24
+
25
+ # @api public
26
+ #
27
+ # @param blk [Proc]
28
+ #
29
+ # @yieldparam [generic<Elem>]
30
+ # @return [void]
31
+ def auto_paging_each(&blk) = (raise NotImplementedError)
32
+
33
+ # @return [Enumerable<generic<Elem>>]
34
+ def to_enum = super(:auto_paging_each)
35
+
36
+ alias_method :enum_for, :to_enum
37
+
38
+ # @api private
39
+ #
40
+ # @param client [PostForMe::Internal::Transport::BaseClient]
41
+ # @param req [Hash{Symbol=>Object}]
42
+ # @param headers [Hash{String=>String}, Net::HTTPHeader]
43
+ # @param page_data [Object]
44
+ def initialize(client:, req:, headers:, page_data:)
45
+ @client = client
46
+ @req = req
47
+ @model = req.fetch(:model)
48
+ super()
49
+ end
50
+
51
+ # rubocop:enable Lint/UnusedMethodArgument
52
+ end
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,77 @@
1
+ # frozen_string_literal: true
2
+
3
+ module PostForMe
4
+ module Internal
5
+ module Type
6
+ # @api private
7
+ #
8
+ # @abstract
9
+ #
10
+ # Ruby has no Boolean class; this is something for models to refer to.
11
+ class Boolean
12
+ extend PostForMe::Internal::Type::Converter
13
+ extend PostForMe::Internal::Util::SorbetRuntimeSupport
14
+
15
+ private_class_method :new
16
+
17
+ # @api public
18
+ #
19
+ # @param other [Object]
20
+ #
21
+ # @return [Boolean]
22
+ def self.===(other) = other == true || other == false
23
+
24
+ # @api public
25
+ #
26
+ # @param other [Object]
27
+ #
28
+ # @return [Boolean]
29
+ def self.==(other) = other.is_a?(Class) && other <= PostForMe::Internal::Type::Boolean
30
+
31
+ class << self
32
+ # @api private
33
+ #
34
+ # Coerce value to Boolean if possible, otherwise return the original value.
35
+ #
36
+ # @param value [Boolean, Object]
37
+ #
38
+ # @param state [Hash{Symbol=>Object}] .
39
+ #
40
+ # @option state [Boolean] :translate_names
41
+ #
42
+ # @option state [Boolean] :strictness
43
+ #
44
+ # @option state [Hash{Symbol=>Object}] :exactness
45
+ #
46
+ # @option state [Class<StandardError>] :error
47
+ #
48
+ # @option state [Integer] :branched
49
+ #
50
+ # @return [Boolean, Object]
51
+ def coerce(value, state:)
52
+ state.fetch(:exactness)[value == true || value == false ? :yes : :no] += 1
53
+ value
54
+ end
55
+
56
+ # @!method dump(value, state:)
57
+ # @api private
58
+ #
59
+ # @param value [Boolean, Object]
60
+ #
61
+ # @param state [Hash{Symbol=>Object}] .
62
+ #
63
+ # @option state [Boolean] :can_retry
64
+ #
65
+ # @return [Boolean, Object]
66
+
67
+ # @api private
68
+ #
69
+ # @return [Object]
70
+ def to_sorbet_type
71
+ T::Boolean
72
+ end
73
+ end
74
+ end
75
+ end
76
+ end
77
+ end