terminal-shop 0.1.0.pre.alpha.15 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +27 -19
- data/lib/terminal-shop/base_client.rb +35 -55
- data/lib/terminal-shop/base_model.rb +457 -438
- data/lib/terminal-shop/base_page.rb +2 -2
- data/lib/terminal-shop/client.rb +1 -1
- data/lib/terminal-shop/errors.rb +3 -2
- data/lib/terminal-shop/models/address_get_params.rb +18 -0
- data/lib/terminal-shop/models/address_get_response.rb +20 -0
- data/lib/terminal-shop/models/app_create_params.rb +14 -2
- data/lib/terminal-shop/models/card_get_params.rb +18 -0
- data/lib/terminal-shop/models/card_get_response.rb +20 -0
- data/lib/terminal-shop/models/cart.rb +35 -2
- data/lib/terminal-shop/models/cart_convert_params.rb +11 -1
- data/lib/terminal-shop/models/cart_redeem_gift_card_params.rb +24 -0
- data/lib/terminal-shop/models/cart_redeem_gift_card_response.rb +48 -0
- data/lib/terminal-shop/models/cart_remove_gift_card_params.rb +18 -0
- data/lib/terminal-shop/models/cart_remove_gift_card_response.rb +19 -0
- data/lib/terminal-shop/models/product.rb +72 -46
- data/lib/terminal-shop/models/product_get_params.rb +18 -0
- data/lib/terminal-shop/models/product_get_response.rb +20 -0
- data/lib/terminal-shop/models/profile_update_params.rb +7 -9
- data/lib/terminal-shop/models/subscription.rb +0 -10
- data/lib/terminal-shop/models/subscription_get_params.rb +18 -0
- data/lib/terminal-shop/models/subscription_get_response.rb +20 -0
- data/lib/terminal-shop/pooled_net_requester.rb +14 -9
- data/lib/terminal-shop/resources/address.rb +19 -0
- data/lib/terminal-shop/resources/app.rb +2 -6
- data/lib/terminal-shop/resources/card.rb +19 -0
- data/lib/terminal-shop/resources/cart.rb +43 -1
- data/lib/terminal-shop/resources/product.rb +19 -0
- data/lib/terminal-shop/resources/profile.rb +3 -3
- data/lib/terminal-shop/resources/subscription.rb +19 -0
- data/lib/terminal-shop/util.rb +135 -1
- data/lib/terminal-shop/version.rb +1 -1
- data/lib/terminal-shop.rb +13 -1
- data/rbi/lib/terminal-shop/base_client.rbi +29 -35
- data/rbi/lib/terminal-shop/base_model.rbi +235 -217
- data/rbi/lib/terminal-shop/base_page.rbi +2 -2
- data/rbi/lib/terminal-shop/client.rbi +2 -2
- data/rbi/lib/terminal-shop/errors.rbi +11 -10
- data/rbi/lib/terminal-shop/models/address.rbi +2 -2
- data/rbi/lib/terminal-shop/models/address_create_params.rbi +3 -13
- data/rbi/lib/terminal-shop/models/address_create_response.rbi +2 -2
- data/rbi/lib/terminal-shop/models/address_delete_params.rbi +5 -2
- data/rbi/lib/terminal-shop/models/address_delete_response.rbi +2 -2
- data/rbi/lib/terminal-shop/models/address_get_params.rbi +21 -0
- data/rbi/lib/terminal-shop/models/address_get_response.rbi +23 -0
- data/rbi/lib/terminal-shop/models/address_list_params.rbi +5 -2
- data/rbi/lib/terminal-shop/models/address_list_response.rbi +2 -2
- data/rbi/lib/terminal-shop/models/app.rbi +2 -2
- data/rbi/lib/terminal-shop/models/app_create_params.rbi +29 -4
- data/rbi/lib/terminal-shop/models/app_create_response.rbi +4 -4
- data/rbi/lib/terminal-shop/models/app_delete_params.rbi +5 -2
- data/rbi/lib/terminal-shop/models/app_delete_response.rbi +2 -2
- data/rbi/lib/terminal-shop/models/app_get_params.rbi +5 -2
- data/rbi/lib/terminal-shop/models/app_get_response.rbi +2 -2
- data/rbi/lib/terminal-shop/models/app_list_params.rbi +5 -2
- data/rbi/lib/terminal-shop/models/app_list_response.rbi +2 -2
- data/rbi/lib/terminal-shop/models/card.rbi +4 -4
- data/rbi/lib/terminal-shop/models/card_collect_params.rbi +5 -2
- data/rbi/lib/terminal-shop/models/card_collect_response.rbi +4 -4
- data/rbi/lib/terminal-shop/models/card_create_params.rbi +2 -2
- data/rbi/lib/terminal-shop/models/card_create_response.rbi +2 -2
- data/rbi/lib/terminal-shop/models/card_delete_params.rbi +5 -2
- data/rbi/lib/terminal-shop/models/card_delete_response.rbi +2 -2
- data/rbi/lib/terminal-shop/models/card_get_params.rbi +21 -0
- data/rbi/lib/terminal-shop/models/card_get_response.rbi +23 -0
- data/rbi/lib/terminal-shop/models/card_list_params.rbi +5 -2
- data/rbi/lib/terminal-shop/models/card_list_response.rbi +2 -2
- data/rbi/lib/terminal-shop/models/cart.rbi +45 -9
- data/rbi/lib/terminal-shop/models/cart_convert_params.rbi +17 -3
- data/rbi/lib/terminal-shop/models/cart_convert_response.rbi +2 -2
- data/rbi/lib/terminal-shop/models/cart_get_params.rbi +5 -2
- data/rbi/lib/terminal-shop/models/cart_get_response.rbi +2 -2
- data/rbi/lib/terminal-shop/models/cart_redeem_gift_card_params.rbi +32 -0
- data/rbi/lib/terminal-shop/models/cart_redeem_gift_card_response.rbi +66 -0
- data/rbi/lib/terminal-shop/models/cart_remove_gift_card_params.rbi +21 -0
- data/rbi/lib/terminal-shop/models/cart_remove_gift_card_response.rbi +23 -0
- data/rbi/lib/terminal-shop/models/cart_set_address_params.rbi +2 -2
- data/rbi/lib/terminal-shop/models/cart_set_address_response.rbi +2 -2
- data/rbi/lib/terminal-shop/models/cart_set_card_params.rbi +2 -2
- data/rbi/lib/terminal-shop/models/cart_set_card_response.rbi +2 -2
- data/rbi/lib/terminal-shop/models/cart_set_item_params.rbi +2 -2
- data/rbi/lib/terminal-shop/models/cart_set_item_response.rbi +2 -2
- data/rbi/lib/terminal-shop/models/email_create_params.rbi +2 -2
- data/rbi/lib/terminal-shop/models/email_create_response.rbi +2 -2
- data/rbi/lib/terminal-shop/models/order.rbi +10 -10
- data/rbi/lib/terminal-shop/models/order_create_params.rbi +2 -2
- data/rbi/lib/terminal-shop/models/order_create_response.rbi +2 -2
- data/rbi/lib/terminal-shop/models/order_get_params.rbi +5 -2
- data/rbi/lib/terminal-shop/models/order_get_response.rbi +2 -2
- data/rbi/lib/terminal-shop/models/order_list_params.rbi +5 -2
- data/rbi/lib/terminal-shop/models/order_list_response.rbi +2 -2
- data/rbi/lib/terminal-shop/models/product.rbi +88 -27
- data/rbi/lib/terminal-shop/models/product_get_params.rbi +21 -0
- data/rbi/lib/terminal-shop/models/product_get_response.rbi +23 -0
- data/rbi/lib/terminal-shop/models/product_list_params.rbi +5 -2
- data/rbi/lib/terminal-shop/models/product_list_response.rbi +2 -2
- data/rbi/lib/terminal-shop/models/product_variant.rbi +2 -2
- data/rbi/lib/terminal-shop/models/profile.rbi +4 -4
- data/rbi/lib/terminal-shop/models/profile_me_params.rbi +5 -2
- data/rbi/lib/terminal-shop/models/profile_me_response.rbi +2 -2
- data/rbi/lib/terminal-shop/models/profile_update_params.rbi +9 -14
- data/rbi/lib/terminal-shop/models/profile_update_response.rbi +2 -2
- data/rbi/lib/terminal-shop/models/subscription.rbi +15 -13
- data/rbi/lib/terminal-shop/models/subscription_create_params.rbi +5 -2
- data/rbi/lib/terminal-shop/models/subscription_create_response.rbi +2 -2
- data/rbi/lib/terminal-shop/models/subscription_delete_params.rbi +5 -2
- data/rbi/lib/terminal-shop/models/subscription_delete_response.rbi +2 -2
- data/rbi/lib/terminal-shop/models/subscription_get_params.rbi +21 -0
- data/rbi/lib/terminal-shop/models/subscription_get_response.rbi +23 -0
- data/rbi/lib/terminal-shop/models/subscription_list_params.rbi +5 -2
- data/rbi/lib/terminal-shop/models/subscription_list_response.rbi +2 -2
- data/rbi/lib/terminal-shop/models/token.rbi +2 -2
- data/rbi/lib/terminal-shop/models/token_create_params.rbi +5 -2
- data/rbi/lib/terminal-shop/models/token_create_response.rbi +4 -4
- data/rbi/lib/terminal-shop/models/token_delete_params.rbi +5 -2
- data/rbi/lib/terminal-shop/models/token_delete_response.rbi +2 -2
- data/rbi/lib/terminal-shop/models/token_get_params.rbi +5 -2
- data/rbi/lib/terminal-shop/models/token_get_response.rbi +2 -2
- data/rbi/lib/terminal-shop/models/token_list_params.rbi +5 -2
- data/rbi/lib/terminal-shop/models/token_list_response.rbi +2 -2
- data/rbi/lib/terminal-shop/models/view_init_params.rbi +5 -2
- data/rbi/lib/terminal-shop/models/view_init_response.rbi +5 -15
- data/rbi/lib/terminal-shop/pooled_net_requester.rbi +12 -10
- data/rbi/lib/terminal-shop/request_options.rbi +4 -0
- data/rbi/lib/terminal-shop/resources/address.rbi +12 -2
- data/rbi/lib/terminal-shop/resources/app.rbi +3 -5
- data/rbi/lib/terminal-shop/resources/card.rbi +12 -2
- data/rbi/lib/terminal-shop/resources/cart.rbi +24 -4
- data/rbi/lib/terminal-shop/resources/email.rbi +2 -2
- data/rbi/lib/terminal-shop/resources/order.rbi +2 -2
- data/rbi/lib/terminal-shop/resources/product.rbi +12 -2
- data/rbi/lib/terminal-shop/resources/profile.rbi +5 -5
- data/rbi/lib/terminal-shop/resources/subscription.rbi +12 -2
- data/rbi/lib/terminal-shop/resources/token.rbi +2 -2
- data/rbi/lib/terminal-shop/resources/view.rbi +2 -2
- data/rbi/lib/terminal-shop/util.rbi +153 -104
- data/rbi/lib/terminal-shop/version.rbi +1 -1
- data/sig/terminal-shop/base_client.rbs +3 -7
- data/sig/terminal-shop/base_page.rbs +1 -1
- data/sig/terminal-shop/errors.rbs +2 -1
- data/sig/terminal-shop/models/address_get_params.rbs +19 -0
- data/sig/terminal-shop/models/address_get_response.rbs +18 -0
- data/sig/terminal-shop/models/app_create_params.rbs +12 -3
- data/sig/terminal-shop/models/card_get_params.rbs +18 -0
- data/sig/terminal-shop/models/card_get_response.rbs +18 -0
- data/sig/terminal-shop/models/cart.rbs +27 -2
- data/sig/terminal-shop/models/cart_convert_params.rbs +10 -2
- data/sig/terminal-shop/models/cart_redeem_gift_card_params.rbs +25 -0
- data/sig/terminal-shop/models/cart_redeem_gift_card_response.rbs +47 -0
- data/sig/terminal-shop/models/cart_remove_gift_card_params.rbs +19 -0
- data/sig/terminal-shop/models/cart_remove_gift_card_response.rbs +18 -0
- data/sig/terminal-shop/models/product.rbs +58 -17
- data/sig/terminal-shop/models/product_get_params.rbs +19 -0
- data/sig/terminal-shop/models/product_get_response.rbs +18 -0
- data/sig/terminal-shop/models/profile_update_params.rbs +5 -5
- data/sig/terminal-shop/models/subscription_get_params.rbs +19 -0
- data/sig/terminal-shop/models/subscription_get_response.rbs +19 -0
- data/sig/terminal-shop/request_options.rbs +4 -0
- data/sig/terminal-shop/resources/address.rbs +10 -0
- data/sig/terminal-shop/resources/app.rbs +0 -2
- data/sig/terminal-shop/resources/card.rbs +10 -0
- data/sig/terminal-shop/resources/cart.rbs +20 -0
- data/sig/terminal-shop/resources/product.rbs +10 -0
- data/sig/terminal-shop/resources/profile.rbs +3 -4
- data/sig/terminal-shop/resources/subscription.rbs +11 -0
- data/sig/terminal-shop/util.rbs +19 -0
- data/sig/terminal-shop/version.rbs +1 -1
- metadata +40 -4
@@ -155,7 +155,7 @@ module TerminalShop
|
|
155
155
|
in [-> { _1 <= Date || _1 <= Time }, String]
|
156
156
|
Kernel.then do
|
157
157
|
[true, target.parse(value), 1]
|
158
|
-
rescue ArgumentError
|
158
|
+
rescue ArgumentError
|
159
159
|
[false, false, 0]
|
160
160
|
end
|
161
161
|
in [_, ^target]
|
@@ -192,33 +192,35 @@ module TerminalShop
|
|
192
192
|
#
|
193
193
|
def self.==(other) = other.is_a?(Class) && other <= TerminalShop::Unknown
|
194
194
|
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
195
|
+
class << self
|
196
|
+
# @!parse
|
197
|
+
# # @private
|
198
|
+
# #
|
199
|
+
# # @param value [Object]
|
200
|
+
# #
|
201
|
+
# # @return [Object]
|
202
|
+
# #
|
203
|
+
# def coerce(value) = super
|
204
|
+
|
205
|
+
# @!parse
|
206
|
+
# # @private
|
207
|
+
# #
|
208
|
+
# # @param value [Object]
|
209
|
+
# #
|
210
|
+
# # @return [Object]
|
211
|
+
# #
|
212
|
+
# def dump(value) = super
|
212
213
|
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
214
|
+
# @private
|
215
|
+
#
|
216
|
+
# @param value [Object]
|
217
|
+
#
|
218
|
+
# @return [Array(true, Object, nil), Array(false, Boolean, Integer)]
|
219
|
+
#
|
220
|
+
def try_strict_coerce(value)
|
221
|
+
# prevent unknown variant from being chosen during the first coercion pass
|
222
|
+
[false, true, 0]
|
223
|
+
end
|
222
224
|
end
|
223
225
|
|
224
226
|
# rubocop:enable Lint/UnusedMethodArgument
|
@@ -246,36 +248,38 @@ module TerminalShop
|
|
246
248
|
#
|
247
249
|
def self.==(other) = other.is_a?(Class) && other <= TerminalShop::BooleanModel
|
248
250
|
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
|
251
|
+
class << self
|
252
|
+
# @!parse
|
253
|
+
# # @private
|
254
|
+
# #
|
255
|
+
# # @param value [Boolean, Object]
|
256
|
+
# #
|
257
|
+
# # @return [Boolean, Object]
|
258
|
+
# #
|
259
|
+
# def coerce(value) = super
|
260
|
+
|
261
|
+
# @!parse
|
262
|
+
# # @private
|
263
|
+
# #
|
264
|
+
# # @param value [Boolean, Object]
|
265
|
+
# #
|
266
|
+
# # @return [Boolean, Object]
|
267
|
+
# #
|
268
|
+
# def dump(value) = super
|
266
269
|
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
|
270
|
+
# @private
|
271
|
+
#
|
272
|
+
# @param value [Object]
|
273
|
+
#
|
274
|
+
# @return [Array(true, Object, nil), Array(false, Boolean, Integer)]
|
275
|
+
#
|
276
|
+
def try_strict_coerce(value)
|
277
|
+
case value
|
278
|
+
in true | false
|
279
|
+
[true, value, 1]
|
280
|
+
else
|
281
|
+
[false, false, 0]
|
282
|
+
end
|
279
283
|
end
|
280
284
|
end
|
281
285
|
end
|
@@ -297,17 +301,19 @@ module TerminalShop
|
|
297
301
|
class Enum
|
298
302
|
extend TerminalShop::Converter
|
299
303
|
|
300
|
-
|
301
|
-
|
302
|
-
|
303
|
-
|
304
|
-
|
304
|
+
class << self
|
305
|
+
# All of the valid Symbol values for this enum.
|
306
|
+
#
|
307
|
+
# @return [Array<NilClass, Boolean, Integer, Float, Symbol>]
|
308
|
+
#
|
309
|
+
def values = (@values ||= constants.map { const_get(_1) })
|
305
310
|
|
306
|
-
|
307
|
-
|
308
|
-
|
309
|
-
|
310
|
-
|
311
|
+
# @private
|
312
|
+
#
|
313
|
+
# Guard against thread safety issues by instantiating `@values`.
|
314
|
+
#
|
315
|
+
private def finalize! = values
|
316
|
+
end
|
311
317
|
|
312
318
|
private_class_method :new
|
313
319
|
|
@@ -325,41 +331,43 @@ module TerminalShop
|
|
325
331
|
other.is_a?(Class) && other <= TerminalShop::Enum && other.values.to_set == values.to_set
|
326
332
|
end
|
327
333
|
|
328
|
-
|
329
|
-
|
330
|
-
|
331
|
-
|
332
|
-
|
333
|
-
|
334
|
-
|
334
|
+
class << self
|
335
|
+
# @private
|
336
|
+
#
|
337
|
+
# @param value [String, Symbol, Object]
|
338
|
+
#
|
339
|
+
# @return [Symbol, Object]
|
340
|
+
#
|
341
|
+
def coerce(value) = (value.is_a?(String) ? value.to_sym : value)
|
335
342
|
|
336
|
-
|
337
|
-
|
338
|
-
|
339
|
-
|
340
|
-
|
341
|
-
|
342
|
-
|
343
|
-
|
343
|
+
# @!parse
|
344
|
+
# # @private
|
345
|
+
# #
|
346
|
+
# # @param value [Symbol, Object]
|
347
|
+
# #
|
348
|
+
# # @return [Symbol, Object]
|
349
|
+
# #
|
350
|
+
# def dump(value) = super
|
344
351
|
|
345
|
-
|
346
|
-
|
347
|
-
|
348
|
-
|
349
|
-
|
350
|
-
|
351
|
-
|
352
|
-
|
352
|
+
# @private
|
353
|
+
#
|
354
|
+
# @param value [Object]
|
355
|
+
#
|
356
|
+
# @return [Array(true, Object, nil), Array(false, Boolean, Integer)]
|
357
|
+
#
|
358
|
+
def try_strict_coerce(value)
|
359
|
+
return [true, value, 1] if values.include?(value)
|
353
360
|
|
354
|
-
|
355
|
-
|
356
|
-
|
357
|
-
else
|
358
|
-
case [value, values.first]
|
359
|
-
in [true | false, true | false] | [Integer, Integer] | [Symbol | String, Symbol]
|
360
|
-
[false, true, 0]
|
361
|
+
case value
|
362
|
+
in String if values.include?(val = value.to_sym)
|
363
|
+
[true, val, 1]
|
361
364
|
else
|
362
|
-
[
|
365
|
+
case [value, values.first]
|
366
|
+
in [true | false, true | false] | [Integer, Integer] | [Symbol | String, Symbol]
|
367
|
+
[false, true, 0]
|
368
|
+
else
|
369
|
+
[false, false, 0]
|
370
|
+
end
|
363
371
|
end
|
364
372
|
end
|
365
373
|
end
|
@@ -372,15 +380,15 @@ module TerminalShop
|
|
372
380
|
class Union
|
373
381
|
extend TerminalShop::Converter
|
374
382
|
|
375
|
-
# @private
|
376
|
-
#
|
377
|
-
# All of the specified variant info for this union.
|
378
|
-
#
|
379
|
-
# @return [Array<Array(Symbol, Proc)>]
|
380
|
-
#
|
381
|
-
private_class_method def self.known_variants = (@known_variants ||= [])
|
382
|
-
|
383
383
|
class << self
|
384
|
+
# @private
|
385
|
+
#
|
386
|
+
# All of the specified variant info for this union.
|
387
|
+
#
|
388
|
+
# @return [Array<Array(Symbol, Proc)>]
|
389
|
+
#
|
390
|
+
private def known_variants = (@known_variants ||= [])
|
391
|
+
|
384
392
|
# @private
|
385
393
|
#
|
386
394
|
# All of the specified variants for this union.
|
@@ -390,68 +398,68 @@ module TerminalShop
|
|
390
398
|
protected def variants
|
391
399
|
@known_variants.map { |key, variant_fn| [key, variant_fn.call] }
|
392
400
|
end
|
393
|
-
end
|
394
401
|
|
395
|
-
|
396
|
-
|
397
|
-
|
398
|
-
|
399
|
-
|
400
|
-
|
401
|
-
in Symbol
|
402
|
-
@discriminator = property
|
403
|
-
end
|
404
|
-
end
|
405
|
-
|
406
|
-
# @private
|
407
|
-
#
|
408
|
-
# @param key [Symbol, Hash{Symbol=>Object}, Proc, TerminalShop::Converter, Class]
|
409
|
-
#
|
410
|
-
# @param spec [Hash{Symbol=>Object}, Proc, TerminalShop::Converter, Class] .
|
411
|
-
#
|
412
|
-
# @option spec [NilClass, TrueClass, FalseClass, Integer, Float, Symbol] :const
|
413
|
-
#
|
414
|
-
# @option spec [Proc] :enum
|
415
|
-
#
|
416
|
-
# @option spec [Proc] :union
|
417
|
-
#
|
418
|
-
# @option spec [Boolean] :"nil?"
|
419
|
-
#
|
420
|
-
private_class_method def self.variant(key, spec = nil)
|
421
|
-
variant_info =
|
422
|
-
case key
|
402
|
+
# @private
|
403
|
+
#
|
404
|
+
# @param property [Symbol]
|
405
|
+
#
|
406
|
+
private def discriminator(property)
|
407
|
+
case property
|
423
408
|
in Symbol
|
424
|
-
|
425
|
-
in Proc | TerminalShop::Converter | Class | Hash
|
426
|
-
[nil, TerminalShop::Converter.type_info(key)]
|
409
|
+
@discriminator = property
|
427
410
|
end
|
411
|
+
end
|
428
412
|
|
429
|
-
|
430
|
-
|
431
|
-
|
432
|
-
|
433
|
-
|
434
|
-
|
435
|
-
|
436
|
-
|
437
|
-
|
438
|
-
|
439
|
-
|
440
|
-
|
441
|
-
|
442
|
-
|
443
|
-
|
444
|
-
|
445
|
-
|
446
|
-
|
447
|
-
|
413
|
+
# @private
|
414
|
+
#
|
415
|
+
# @param key [Symbol, Hash{Symbol=>Object}, Proc, TerminalShop::Converter, Class]
|
416
|
+
#
|
417
|
+
# @param spec [Hash{Symbol=>Object}, Proc, TerminalShop::Converter, Class] .
|
418
|
+
#
|
419
|
+
# @option spec [NilClass, TrueClass, FalseClass, Integer, Float, Symbol] :const
|
420
|
+
#
|
421
|
+
# @option spec [Proc] :enum
|
422
|
+
#
|
423
|
+
# @option spec [Proc] :union
|
424
|
+
#
|
425
|
+
# @option spec [Boolean] :"nil?"
|
426
|
+
#
|
427
|
+
private def variant(key, spec = nil)
|
428
|
+
variant_info =
|
429
|
+
case key
|
430
|
+
in Symbol
|
431
|
+
[key, TerminalShop::Converter.type_info(spec)]
|
432
|
+
in Proc | TerminalShop::Converter | Class | Hash
|
433
|
+
[nil, TerminalShop::Converter.type_info(key)]
|
448
434
|
end
|
449
435
|
|
450
|
-
|
451
|
-
|
452
|
-
|
453
|
-
|
454
|
-
|
436
|
+
known_variants << variant_info
|
437
|
+
end
|
438
|
+
|
439
|
+
# @private
|
440
|
+
#
|
441
|
+
# @param value [Object]
|
442
|
+
#
|
443
|
+
# @return [TerminalShop::Converter, Class, nil]
|
444
|
+
#
|
445
|
+
private def resolve_variant(value)
|
446
|
+
case [@discriminator, value]
|
447
|
+
in [_, TerminalShop::BaseModel]
|
448
|
+
value.class
|
449
|
+
in [Symbol, Hash]
|
450
|
+
key =
|
451
|
+
if value.key?(@discriminator)
|
452
|
+
value.fetch(@discriminator)
|
453
|
+
elsif value.key?((discriminator = @discriminator.to_s))
|
454
|
+
value.fetch(discriminator)
|
455
|
+
end
|
456
|
+
|
457
|
+
key = key.to_sym if key.is_a?(String)
|
458
|
+
_, resolved = known_variants.find { |k,| k == key }
|
459
|
+
resolved.nil? ? TerminalShop::Unknown : resolved.call
|
460
|
+
else
|
461
|
+
nil
|
462
|
+
end
|
455
463
|
end
|
456
464
|
end
|
457
465
|
|
@@ -478,87 +486,89 @@ module TerminalShop
|
|
478
486
|
other.is_a?(Class) && other <= TerminalShop::Union && other.variants == variants
|
479
487
|
end
|
480
488
|
|
481
|
-
|
482
|
-
|
483
|
-
|
484
|
-
|
485
|
-
|
486
|
-
|
487
|
-
|
488
|
-
|
489
|
-
|
490
|
-
|
489
|
+
class << self
|
490
|
+
# @private
|
491
|
+
#
|
492
|
+
# @param value [Object]
|
493
|
+
#
|
494
|
+
# @return [Object]
|
495
|
+
#
|
496
|
+
def coerce(value)
|
497
|
+
if (variant = resolve_variant(value))
|
498
|
+
return TerminalShop::Converter.coerce(variant, value)
|
499
|
+
end
|
491
500
|
|
492
|
-
|
501
|
+
matches = []
|
493
502
|
|
494
|
-
|
495
|
-
|
503
|
+
known_variants.each do |_, variant_fn|
|
504
|
+
variant = variant_fn.call
|
496
505
|
|
497
|
-
|
498
|
-
|
499
|
-
|
500
|
-
|
501
|
-
|
502
|
-
|
503
|
-
|
506
|
+
case TerminalShop::Converter.try_strict_coerce(variant, value)
|
507
|
+
in [true, coerced, _]
|
508
|
+
return coerced
|
509
|
+
in [false, true, score]
|
510
|
+
matches << [score, variant]
|
511
|
+
in [false, false, _]
|
512
|
+
nil
|
513
|
+
end
|
504
514
|
end
|
505
|
-
end
|
506
|
-
|
507
|
-
_, variant = matches.sort! { _2.first <=> _1.first }.find { |score,| !score.zero? }
|
508
|
-
variant.nil? ? value : TerminalShop::Converter.coerce(variant, value)
|
509
|
-
end
|
510
515
|
|
511
|
-
|
512
|
-
|
513
|
-
# @param value [Object]
|
514
|
-
#
|
515
|
-
# @return [Object]
|
516
|
-
#
|
517
|
-
def self.dump(value)
|
518
|
-
if (variant = resolve_variant(value))
|
519
|
-
return TerminalShop::Converter.dump(variant, value)
|
516
|
+
_, variant = matches.sort! { _2.first <=> _1.first }.find { |score,| !score.zero? }
|
517
|
+
variant.nil? ? value : TerminalShop::Converter.coerce(variant, value)
|
520
518
|
end
|
521
519
|
|
522
|
-
|
523
|
-
|
524
|
-
|
520
|
+
# @private
|
521
|
+
#
|
522
|
+
# @param value [Object]
|
523
|
+
#
|
524
|
+
# @return [Object]
|
525
|
+
#
|
526
|
+
def dump(value)
|
527
|
+
if (variant = resolve_variant(value))
|
525
528
|
return TerminalShop::Converter.dump(variant, value)
|
526
529
|
end
|
527
|
-
end
|
528
|
-
value
|
529
|
-
end
|
530
530
|
|
531
|
-
|
532
|
-
|
533
|
-
|
534
|
-
|
535
|
-
|
536
|
-
|
537
|
-
|
538
|
-
# TODO(ruby) this will result in super linear decoding behaviour for nested unions
|
539
|
-
# follow up with a decoding context that captures current strictness levels
|
540
|
-
if (variant = resolve_variant(value))
|
541
|
-
return Converter.try_strict_coerce(variant, value)
|
531
|
+
known_variants.each do |_, variant_fn|
|
532
|
+
variant = variant_fn.call
|
533
|
+
if variant === value
|
534
|
+
return TerminalShop::Converter.dump(variant, value)
|
535
|
+
end
|
536
|
+
end
|
537
|
+
value
|
542
538
|
end
|
543
539
|
|
544
|
-
|
545
|
-
|
540
|
+
# @private
|
541
|
+
#
|
542
|
+
# @param value [Object]
|
543
|
+
#
|
544
|
+
# @return [Array(true, Object, nil), Array(false, Boolean, Integer)]
|
545
|
+
#
|
546
|
+
def try_strict_coerce(value)
|
547
|
+
# TODO(ruby) this will result in super linear decoding behaviour for nested unions
|
548
|
+
# follow up with a decoding context that captures current strictness levels
|
549
|
+
if (variant = resolve_variant(value))
|
550
|
+
return Converter.try_strict_coerce(variant, value)
|
551
|
+
end
|
546
552
|
|
547
|
-
|
548
|
-
|
553
|
+
coercible = false
|
554
|
+
max_score = 0
|
549
555
|
|
550
|
-
|
551
|
-
|
552
|
-
|
553
|
-
|
554
|
-
|
555
|
-
|
556
|
-
|
557
|
-
|
556
|
+
known_variants.each do |_, variant_fn|
|
557
|
+
variant = variant_fn.call
|
558
|
+
|
559
|
+
case TerminalShop::Converter.try_strict_coerce(variant, value)
|
560
|
+
in [true, coerced, score]
|
561
|
+
return [true, coerced, score]
|
562
|
+
in [false, true, score]
|
563
|
+
coercible = true
|
564
|
+
max_score = [max_score, score].max
|
565
|
+
in [false, false, _]
|
566
|
+
nil
|
567
|
+
end
|
558
568
|
end
|
559
|
-
end
|
560
569
|
|
561
|
-
|
570
|
+
[false, coercible, max_score]
|
571
|
+
end
|
562
572
|
end
|
563
573
|
|
564
574
|
# rubocop:enable Style/CaseEquality
|
@@ -839,23 +849,30 @@ module TerminalShop
|
|
839
849
|
#
|
840
850
|
# @abstract
|
841
851
|
#
|
852
|
+
# @example
|
853
|
+
# ```ruby
|
854
|
+
# # `product_api` is a `TerminalShop::Models::ProductAPI`
|
855
|
+
# product_api => {
|
856
|
+
# id: id,
|
857
|
+
# description: description,
|
858
|
+
# name: name
|
859
|
+
# }
|
860
|
+
# ```
|
842
861
|
class BaseModel
|
843
862
|
extend TerminalShop::Converter
|
844
863
|
|
845
|
-
# @private
|
846
|
-
#
|
847
|
-
# Assumes superclass fields are totally defined before fields are accessed /
|
848
|
-
# defined on subclasses.
|
849
|
-
#
|
850
|
-
# @return [Hash{Symbol=>Hash{Symbol=>Object}}]
|
851
|
-
#
|
852
|
-
def self.known_fields
|
853
|
-
@known_fields ||= (self < TerminalShop::BaseModel ? superclass.known_fields.dup : {})
|
854
|
-
end
|
855
|
-
|
856
864
|
class << self
|
857
865
|
# @private
|
858
866
|
#
|
867
|
+
# Assumes superclass fields are totally defined before fields are accessed /
|
868
|
+
# defined on subclasses.
|
869
|
+
#
|
870
|
+
# @return [Hash{Symbol=>Hash{Symbol=>Object}}]
|
871
|
+
#
|
872
|
+
def known_fields
|
873
|
+
@known_fields ||= (self < TerminalShop::BaseModel ? superclass.known_fields.dup : {})
|
874
|
+
end
|
875
|
+
|
859
876
|
# @return [Hash{Symbol=>Hash{Symbol=>Object}}]
|
860
877
|
#
|
861
878
|
def fields
|
@@ -863,135 +880,135 @@ module TerminalShop
|
|
863
880
|
{**field.except(:type_fn), type: field.fetch(:type_fn).call}
|
864
881
|
end
|
865
882
|
end
|
866
|
-
end
|
867
883
|
|
868
|
-
|
869
|
-
|
870
|
-
|
871
|
-
|
872
|
-
|
884
|
+
# @private
|
885
|
+
#
|
886
|
+
# @return [Hash{Symbol=>Proc}]
|
887
|
+
#
|
888
|
+
def defaults = (@defaults ||= {})
|
873
889
|
|
874
|
-
|
875
|
-
|
876
|
-
|
877
|
-
|
878
|
-
|
879
|
-
|
880
|
-
|
881
|
-
|
882
|
-
|
883
|
-
|
884
|
-
|
885
|
-
|
886
|
-
|
887
|
-
|
888
|
-
|
889
|
-
|
890
|
-
|
891
|
-
|
892
|
-
|
893
|
-
|
894
|
-
|
895
|
-
|
896
|
-
|
897
|
-
|
898
|
-
|
899
|
-
|
890
|
+
# @private
|
891
|
+
#
|
892
|
+
# @param name_sym [Symbol]
|
893
|
+
#
|
894
|
+
# @param required [Boolean]
|
895
|
+
#
|
896
|
+
# @param type_info [Hash{Symbol=>Object}, Proc, TerminalShop::Converter, Class]
|
897
|
+
#
|
898
|
+
# @param spec [Hash{Symbol=>Object}] .
|
899
|
+
#
|
900
|
+
# @option spec [NilClass, TrueClass, FalseClass, Integer, Float, Symbol] :const
|
901
|
+
#
|
902
|
+
# @option spec [Proc] :enum
|
903
|
+
#
|
904
|
+
# @option spec [Proc] :union
|
905
|
+
#
|
906
|
+
# @option spec [Boolean] :"nil?"
|
907
|
+
#
|
908
|
+
private def add_field(name_sym, required:, type_info:, spec:)
|
909
|
+
type_fn, info =
|
910
|
+
case type_info
|
911
|
+
in Proc | Class | TerminalShop::Converter
|
912
|
+
[TerminalShop::Converter.type_info({**spec, union: type_info}), spec]
|
913
|
+
in Hash
|
914
|
+
[TerminalShop::Converter.type_info(type_info), type_info]
|
915
|
+
end
|
900
916
|
|
901
|
-
|
902
|
-
|
917
|
+
fallback = info[:const]
|
918
|
+
defaults[name_sym] = fallback if required && !info[:nil?] && info.key?(:const)
|
903
919
|
|
904
|
-
|
905
|
-
|
920
|
+
key = info.fetch(:api_name, name_sym)
|
921
|
+
setter = "#{name_sym}="
|
906
922
|
|
907
|
-
|
908
|
-
|
909
|
-
|
923
|
+
if known_fields.key?(name_sym)
|
924
|
+
[name_sym, setter].each { undef_method(_1) }
|
925
|
+
end
|
910
926
|
|
911
|
-
|
927
|
+
known_fields[name_sym] = {mode: @mode, key: key, required: required, type_fn: type_fn}
|
912
928
|
|
913
|
-
|
914
|
-
|
915
|
-
|
929
|
+
define_method(setter) do |val|
|
930
|
+
@data[key] = val
|
931
|
+
end
|
916
932
|
|
917
|
-
|
918
|
-
|
919
|
-
|
920
|
-
|
921
|
-
|
922
|
-
|
923
|
-
|
924
|
-
|
925
|
-
|
926
|
-
|
933
|
+
define_method(name_sym) do
|
934
|
+
field_type = type_fn.call
|
935
|
+
value = @data.fetch(key) { self.class.defaults[key] }
|
936
|
+
TerminalShop::Converter.coerce(field_type, value)
|
937
|
+
rescue StandardError
|
938
|
+
name = self.class.name.split("::").last
|
939
|
+
raise TerminalShop::ConversionError.new(
|
940
|
+
"Failed to parse #{name}.#{name_sym} as #{field_type.inspect}. " \
|
941
|
+
"To get the unparsed API response, use #{name}[:#{key}]."
|
942
|
+
)
|
943
|
+
end
|
927
944
|
end
|
928
|
-
end
|
929
945
|
|
930
|
-
|
931
|
-
|
932
|
-
|
933
|
-
|
934
|
-
|
935
|
-
|
936
|
-
|
937
|
-
|
938
|
-
|
939
|
-
|
940
|
-
|
941
|
-
|
942
|
-
|
943
|
-
|
944
|
-
|
945
|
-
|
946
|
-
|
947
|
-
|
948
|
-
|
946
|
+
# @private
|
947
|
+
#
|
948
|
+
# @param name_sym [Symbol]
|
949
|
+
#
|
950
|
+
# @param type_info [Hash{Symbol=>Object}, Proc, TerminalShop::Converter, Class]
|
951
|
+
#
|
952
|
+
# @param spec [Hash{Symbol=>Object}] .
|
953
|
+
#
|
954
|
+
# @option spec [NilClass, TrueClass, FalseClass, Integer, Float, Symbol] :const
|
955
|
+
#
|
956
|
+
# @option spec [Proc] :enum
|
957
|
+
#
|
958
|
+
# @option spec [Proc] :union
|
959
|
+
#
|
960
|
+
# @option spec [Boolean] :"nil?"
|
961
|
+
#
|
962
|
+
def required(name_sym, type_info, spec = {})
|
963
|
+
add_field(name_sym, required: true, type_info: type_info, spec: spec)
|
964
|
+
end
|
949
965
|
|
950
|
-
|
951
|
-
|
952
|
-
|
953
|
-
|
954
|
-
|
955
|
-
|
956
|
-
|
957
|
-
|
958
|
-
|
959
|
-
|
960
|
-
|
961
|
-
|
962
|
-
|
963
|
-
|
964
|
-
|
965
|
-
|
966
|
-
|
967
|
-
|
968
|
-
|
966
|
+
# @private
|
967
|
+
#
|
968
|
+
# @param name_sym [Symbol]
|
969
|
+
#
|
970
|
+
# @param type_info [Hash{Symbol=>Object}, Proc, TerminalShop::Converter, Class]
|
971
|
+
#
|
972
|
+
# @param spec [Hash{Symbol=>Object}] .
|
973
|
+
#
|
974
|
+
# @option spec [NilClass, TrueClass, FalseClass, Integer, Float, Symbol] :const
|
975
|
+
#
|
976
|
+
# @option spec [Proc] :enum
|
977
|
+
#
|
978
|
+
# @option spec [Proc] :union
|
979
|
+
#
|
980
|
+
# @option spec [Boolean] :"nil?"
|
981
|
+
#
|
982
|
+
def optional(name_sym, type_info, spec = {})
|
983
|
+
add_field(name_sym, required: false, type_info: type_info, spec: spec)
|
984
|
+
end
|
969
985
|
|
970
|
-
|
971
|
-
|
972
|
-
|
973
|
-
|
974
|
-
|
975
|
-
|
976
|
-
|
977
|
-
|
978
|
-
|
979
|
-
|
980
|
-
|
981
|
-
|
982
|
-
|
986
|
+
# @private
|
987
|
+
#
|
988
|
+
# `request_only` attributes not excluded from `.#coerce` when receiving responses
|
989
|
+
# even if well behaved servers should not send them
|
990
|
+
#
|
991
|
+
# @param blk [Proc]
|
992
|
+
#
|
993
|
+
private def request_only(&blk)
|
994
|
+
@mode = :dump
|
995
|
+
blk.call
|
996
|
+
ensure
|
997
|
+
@mode = nil
|
998
|
+
end
|
983
999
|
|
984
|
-
|
985
|
-
|
986
|
-
|
987
|
-
|
988
|
-
|
989
|
-
|
990
|
-
|
991
|
-
|
992
|
-
|
993
|
-
|
994
|
-
|
1000
|
+
# @private
|
1001
|
+
#
|
1002
|
+
# `response_only` attributes are omitted from `.#dump` when making requests
|
1003
|
+
#
|
1004
|
+
# @param blk [Proc]
|
1005
|
+
#
|
1006
|
+
private def response_only(&blk)
|
1007
|
+
@mode = :coerce
|
1008
|
+
blk.call
|
1009
|
+
ensure
|
1010
|
+
@mode = nil
|
1011
|
+
end
|
995
1012
|
end
|
996
1013
|
|
997
1014
|
# @param other [Object]
|
@@ -1007,108 +1024,110 @@ module TerminalShop
|
|
1007
1024
|
end
|
1008
1025
|
end
|
1009
1026
|
|
1010
|
-
|
1011
|
-
|
1012
|
-
|
1013
|
-
|
1014
|
-
|
1015
|
-
|
1016
|
-
|
1017
|
-
|
1018
|
-
|
1019
|
-
|
1020
|
-
|
1021
|
-
|
1027
|
+
class << self
|
1028
|
+
# @private
|
1029
|
+
#
|
1030
|
+
# @param value [TerminalShop::BaseModel, Hash{Object=>Object}, Object]
|
1031
|
+
#
|
1032
|
+
# @return [TerminalShop::BaseModel, Object]
|
1033
|
+
#
|
1034
|
+
def coerce(value)
|
1035
|
+
case TerminalShop::Util.coerce_hash(value)
|
1036
|
+
in Hash => coerced
|
1037
|
+
new(coerced)
|
1038
|
+
else
|
1039
|
+
value
|
1040
|
+
end
|
1022
1041
|
end
|
1023
|
-
end
|
1024
1042
|
|
1025
|
-
|
1026
|
-
|
1027
|
-
|
1028
|
-
|
1029
|
-
|
1030
|
-
|
1031
|
-
|
1032
|
-
|
1033
|
-
|
1034
|
-
|
1043
|
+
# @private
|
1044
|
+
#
|
1045
|
+
# @param value [TerminalShop::BaseModel, Object]
|
1046
|
+
#
|
1047
|
+
# @return [Hash{Object=>Object}, Object]
|
1048
|
+
#
|
1049
|
+
def dump(value)
|
1050
|
+
unless (coerced = TerminalShop::Util.coerce_hash(value)).is_a?(Hash)
|
1051
|
+
return value
|
1052
|
+
end
|
1035
1053
|
|
1036
|
-
|
1037
|
-
|
1038
|
-
|
1039
|
-
|
1040
|
-
|
1041
|
-
else
|
1042
|
-
mode, type_fn, api_name = field.fetch_values(:mode, :type_fn, :key)
|
1043
|
-
case mode
|
1044
|
-
in :coerce
|
1045
|
-
next
|
1054
|
+
values = coerced.filter_map do |key, val|
|
1055
|
+
name = key.to_sym
|
1056
|
+
case (field = known_fields[name])
|
1057
|
+
in nil
|
1058
|
+
[name, val]
|
1046
1059
|
else
|
1047
|
-
|
1048
|
-
|
1060
|
+
mode, type_fn, api_name = field.fetch_values(:mode, :type_fn, :key)
|
1061
|
+
case mode
|
1062
|
+
in :coerce
|
1063
|
+
next
|
1064
|
+
else
|
1065
|
+
target = type_fn.call
|
1066
|
+
[api_name, TerminalShop::Converter.dump(target, val)]
|
1067
|
+
end
|
1049
1068
|
end
|
1050
|
-
end
|
1051
|
-
end.to_h
|
1069
|
+
end.to_h
|
1052
1070
|
|
1053
|
-
|
1054
|
-
|
1071
|
+
defaults.each do |key, val|
|
1072
|
+
next if values.key?(key)
|
1055
1073
|
|
1056
|
-
|
1057
|
-
|
1058
|
-
|
1059
|
-
values
|
1060
|
-
end
|
1074
|
+
values[key] = val
|
1075
|
+
end
|
1061
1076
|
|
1062
|
-
|
1063
|
-
#
|
1064
|
-
# @param value [Object]
|
1065
|
-
#
|
1066
|
-
# @return [Array(true, Object, nil), Array(false, Boolean, Integer)]
|
1067
|
-
#
|
1068
|
-
def self.try_strict_coerce(value)
|
1069
|
-
case value
|
1070
|
-
in Hash | TerminalShop::BaseModel
|
1071
|
-
value = value.to_h
|
1072
|
-
else
|
1073
|
-
return [false, false, 0]
|
1077
|
+
values
|
1074
1078
|
end
|
1075
1079
|
|
1076
|
-
|
1077
|
-
|
1078
|
-
|
1079
|
-
|
1080
|
+
# @private
|
1081
|
+
#
|
1082
|
+
# @param value [Object]
|
1083
|
+
#
|
1084
|
+
# @return [Array(true, Object, nil), Array(false, Boolean, Integer)]
|
1085
|
+
#
|
1086
|
+
def try_strict_coerce(value)
|
1087
|
+
case value
|
1088
|
+
in Hash | TerminalShop::BaseModel
|
1089
|
+
value = value.to_h
|
1090
|
+
else
|
1091
|
+
return [false, false, 0]
|
1092
|
+
end
|
1093
|
+
|
1094
|
+
keys = value.keys.to_set
|
1095
|
+
great_success = true
|
1096
|
+
tally = 0
|
1097
|
+
acc = {}
|
1080
1098
|
|
1081
|
-
|
1082
|
-
|
1083
|
-
|
1099
|
+
known_fields.each_value do |field|
|
1100
|
+
mode, required, type_fn, api_name = field.fetch_values(:mode, :required, :type_fn, :key)
|
1101
|
+
keys.delete(api_name)
|
1084
1102
|
|
1085
|
-
|
1086
|
-
|
1087
|
-
|
1088
|
-
|
1089
|
-
|
1090
|
-
|
1091
|
-
|
1092
|
-
|
1093
|
-
|
1103
|
+
case [required && mode != :dump, value.key?(api_name)]
|
1104
|
+
in [_, true]
|
1105
|
+
target = type_fn.call
|
1106
|
+
item = value.fetch(api_name)
|
1107
|
+
case TerminalShop::Converter.try_strict_coerce(target, item)
|
1108
|
+
in [true, coerced, score]
|
1109
|
+
tally += score
|
1110
|
+
acc[api_name] = coerced
|
1111
|
+
in [false, true, score]
|
1112
|
+
great_success = false
|
1113
|
+
tally += score
|
1114
|
+
acc[api_name] = item
|
1115
|
+
in [false, false, _]
|
1116
|
+
great_success &&= item.nil?
|
1117
|
+
end
|
1118
|
+
in [true, false]
|
1094
1119
|
great_success = false
|
1095
|
-
|
1096
|
-
|
1097
|
-
in [false, false, _]
|
1098
|
-
great_success &&= item.nil?
|
1120
|
+
in [false, false]
|
1121
|
+
nil
|
1099
1122
|
end
|
1100
|
-
in [true, false]
|
1101
|
-
great_success = false
|
1102
|
-
in [false, false]
|
1103
|
-
nil
|
1104
1123
|
end
|
1105
|
-
end
|
1106
1124
|
|
1107
|
-
|
1108
|
-
|
1109
|
-
|
1125
|
+
keys.each do |key|
|
1126
|
+
acc[key] = value.fetch(key)
|
1127
|
+
end
|
1110
1128
|
|
1111
|
-
|
1129
|
+
great_success ? [true, new(acc), tally] : [false, true, tally]
|
1130
|
+
end
|
1112
1131
|
end
|
1113
1132
|
|
1114
1133
|
# Returns the raw value associated with the given key, if found. Otherwise, nil is
|