e_plat 0.2.4 → 0.4.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 +633 -135
- data/lib/active_resource/connection_error.rb +29 -0
- data/lib/active_resource/formats.rb +27 -0
- data/lib/current.rb +7 -0
- data/lib/e_plat/client/default_request_args.rb +27 -3
- data/lib/e_plat/client.rb +114 -87
- data/lib/e_plat/connection.rb +4 -0
- data/lib/e_plat/errors/missing_session_error.rb +1 -1
- data/lib/e_plat/mapping/base.rb +119 -12
- data/lib/e_plat/mapping/bigcommerce/v_3/metafield.rb +62 -0
- data/lib/e_plat/mapping/bigcommerce/v_3/order/billing_address.rb +14 -0
- data/lib/e_plat/mapping/bigcommerce/v_3/order/line_item.rb +85 -0
- data/lib/e_plat/mapping/bigcommerce/v_3/order/shipping_address.rb +73 -0
- data/lib/e_plat/mapping/bigcommerce/v_3/order.rb +160 -0
- data/lib/e_plat/mapping/bigcommerce/v_3/product/image.rb +12 -12
- data/lib/e_plat/mapping/bigcommerce/v_3/product/variant.rb +1 -1
- data/lib/e_plat/mapping/bigcommerce/v_3/script_tag.rb +78 -0
- data/lib/e_plat/mapping/bigcommerce/v_3/shop.rb +11 -6
- data/lib/e_plat/mapping/bigcommerce/v_3/webhook.rb +54 -0
- data/lib/e_plat/mapping/request_body_root.rb +38 -0
- data/lib/e_plat/mapping/shopify/v_2024_01/metafield.rb +26 -0
- data/lib/e_plat/mapping/shopify/v_2024_01/order/billing_address.rb +14 -0
- data/lib/e_plat/mapping/shopify/v_2024_01/order/shipping_address.rb +30 -0
- data/lib/e_plat/mapping/shopify/{v_2022_07/product.rb → v_2024_01/order.rb} +3 -3
- data/lib/e_plat/mapping/shopify/{v_2022_07 → v_2024_01}/product/image.rb +1 -1
- data/lib/e_plat/mapping/shopify/{v_2022_07 → v_2024_01}/product/variant.rb +2 -1
- data/lib/e_plat/mapping/shopify/v_2024_01/product.rb +26 -0
- data/lib/e_plat/mapping/shopify/v_2024_01/script_tag.rb +26 -0
- data/lib/e_plat/mapping/shopify/{v_2022_07 → v_2024_01}/shop.rb +1 -1
- data/lib/e_plat/mapping/shopify/v_2024_01/webhook.rb +29 -0
- data/lib/e_plat/mapping/virtual_collection/base.rb +14 -0
- data/lib/e_plat/mapping/virtual_collection/bigcommerce/order_line_items.rb +297 -0
- data/lib/e_plat/mapping.rb +3 -3
- data/lib/e_plat/resource/attribute_interface.rb +28 -28
- data/lib/e_plat/resource/base.rb +107 -68
- data/lib/e_plat/resource/collection.rb +92 -0
- data/lib/e_plat/resource/concerns/aliases.rb +102 -18
- data/lib/e_plat/resource/concerns/dirty.rb +54 -0
- data/lib/e_plat/resource/concerns/metafieldable.rb +43 -0
- data/lib/e_plat/resource/concerns/overwrite_instance_methods.rb +108 -6
- data/lib/e_plat/resource/concerns/overwrite_request_methods.rb +73 -37
- data/lib/e_plat/resource/countable.rb +43 -0
- data/lib/e_plat/resource/metafield.rb +70 -0
- data/lib/e_plat/resource/order/Consignment.rb +8 -0
- data/lib/e_plat/resource/order/billing_address.rb +6 -0
- data/lib/e_plat/resource/order/fulfillment.rb +1 -0
- data/lib/e_plat/resource/order/line_item.rb +1 -0
- data/lib/e_plat/resource/order/shipping_address.rb +44 -0
- data/lib/e_plat/resource/order/shipping_line.rb +15 -14
- data/lib/e_plat/resource/order.rb +32 -0
- data/lib/e_plat/resource/paginated/link_headers.rb +42 -0
- data/lib/e_plat/resource/paginated/link_params.rb +26 -0
- data/lib/e_plat/resource/product/image.rb +6 -0
- data/lib/e_plat/resource/product/option.rb +1 -0
- data/lib/e_plat/resource/product/variant.rb +8 -12
- data/lib/e_plat/resource/product.rb +8 -2
- data/lib/e_plat/resource/script_tag.rb +56 -0
- data/lib/e_plat/resource/shop.rb +17 -13
- data/lib/e_plat/resource/shopify_only/recurring_application_charge/usage_charge.rb +32 -0
- data/lib/e_plat/resource/shopify_only/recurring_application_charge.rb +47 -0
- data/lib/e_plat/resource/webhook.rb +50 -0
- data/lib/e_plat/session.rb +14 -14
- data/lib/e_plat/type_coercer.rb +15 -17
- data/lib/e_plat/types.rb +1 -1
- data/lib/e_plat/version.rb +1 -1
- data/lib/e_plat.rb +4 -4
- metadata +51 -19
- data/lib/e_plat/resource/order/customer.rb +0 -37
- data/lib/e_plat/session_state.rb +0 -25
@@ -0,0 +1,29 @@
|
|
1
|
+
module EPlat
|
2
|
+
class Mapping
|
3
|
+
module Shopify
|
4
|
+
module V202401 #< :module
|
5
|
+
class Webhook < EPlat::Mapping::Base
|
6
|
+
DEFAULT_VALUES = {
|
7
|
+
format: "json"
|
8
|
+
}
|
9
|
+
|
10
|
+
def native_top_key
|
11
|
+
"webhook"
|
12
|
+
end
|
13
|
+
|
14
|
+
def native_attributes
|
15
|
+
super.concat([
|
16
|
+
])
|
17
|
+
end
|
18
|
+
|
19
|
+
def native_attribute_aliases
|
20
|
+
super.concat([
|
21
|
+
])
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
@@ -0,0 +1,14 @@
|
|
1
|
+
|
2
|
+
module EPlat
|
3
|
+
class Mapping
|
4
|
+
class VirtualCollection::Base
|
5
|
+
attr_accessor :resource
|
6
|
+
# useful for adding an interface that gets and sets from nested attributes accross nested resources
|
7
|
+
# for example a order.line_items collection that is aliased to attributes in both order.consignments[0].shipping and order.consignments[0].shipping.line_items
|
8
|
+
|
9
|
+
def initialize(resource:, map_from:)
|
10
|
+
end
|
11
|
+
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,297 @@
|
|
1
|
+
|
2
|
+
module EPlat
|
3
|
+
class Mapping
|
4
|
+
module VirtualCollection
|
5
|
+
module Bigcommerce
|
6
|
+
class OrderLineItems < VirtualCollection::Base
|
7
|
+
attr_accessor :resource
|
8
|
+
# will create an array of EPlat::Order::LineItem objects with no proper attributes, only aliases
|
9
|
+
# i.e. e_plat_key will always be virtual, whilst the native key will point to a proper attributes other resources
|
10
|
+
# Order line_items do actually exist in BigCommerce, but they're in a much deeper level of the JSON that order.line_items
|
11
|
+
# Using a virtual collection, allows us to treat the line_items as if they were in the proper position: order.line_items
|
12
|
+
|
13
|
+
def initialize(resource:, map_from:)
|
14
|
+
@resource = resource
|
15
|
+
super
|
16
|
+
|
17
|
+
return unless @resource.try :consignments #map_from
|
18
|
+
|
19
|
+
@resource.line_items =
|
20
|
+
(@resource.consignments[0].try(:shipping).presence || @resource.consignments[0].try(:pickups))&.first&.line_items.map.with_index do |data, i|
|
21
|
+
item = EPlat::Order::LineItem.new(order_id: @resource.id)
|
22
|
+
item.mapping.virtual_collection = self
|
23
|
+
item.add_aliases!(native_attribute_aliases(i), EPlat::Order::LineItem.schema)
|
24
|
+
|
25
|
+
item
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def native_attribute_aliases(i)
|
30
|
+
[
|
31
|
+
{
|
32
|
+
alias_attribute: {
|
33
|
+
native_key: "[consignments][0][shipping][0][line_items][#{i}][id]",
|
34
|
+
e_plat_key: "id",
|
35
|
+
virtual_collection: true
|
36
|
+
}
|
37
|
+
},
|
38
|
+
{
|
39
|
+
alias_attribute: {
|
40
|
+
native_key: "[consignments][0][shipping][0][line_items][#{i}][variant_id]",
|
41
|
+
e_plat_key: "variant_id",
|
42
|
+
virtual_collection: true
|
43
|
+
}
|
44
|
+
},
|
45
|
+
{
|
46
|
+
alias_attribute: {
|
47
|
+
native_key: "[consignments][0][shipping][0][line_items][#{i}][name]",
|
48
|
+
e_plat_key: "name",
|
49
|
+
virtual_collection: true
|
50
|
+
}
|
51
|
+
},
|
52
|
+
{
|
53
|
+
alias_attribute: {
|
54
|
+
native_key: "[consignments][0][shipping][0][line_items][#{i}][price]",
|
55
|
+
e_plat_key: "price",
|
56
|
+
virtual_collection: true
|
57
|
+
}
|
58
|
+
},
|
59
|
+
{
|
60
|
+
alias_attribute: {
|
61
|
+
native_key: "[consignments][0][shipping][0][line_items][#{i}][product_id]",
|
62
|
+
e_plat_key: "product_id",
|
63
|
+
virtual_collection: true
|
64
|
+
}
|
65
|
+
},
|
66
|
+
{
|
67
|
+
alias_attribute: {
|
68
|
+
native_key: "[consignments][0][shipping][0][line_items][#{i}][quantity]",
|
69
|
+
e_plat_key: "quantity",
|
70
|
+
virtual_collection: true
|
71
|
+
}
|
72
|
+
},
|
73
|
+
{
|
74
|
+
alias_attribute: {
|
75
|
+
native_key: "[consignments][0][shipping][0][line_items][#{i}][sku]",
|
76
|
+
e_plat_key: "sku",
|
77
|
+
virtual_collection: true
|
78
|
+
}
|
79
|
+
},
|
80
|
+
]
|
81
|
+
end
|
82
|
+
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
|
90
|
+
|
91
|
+
# consignments are deliveries, we're just going to operate within the context on one delivery per order
|
92
|
+
# this should be reasonable to tie us over for now
|
93
|
+
|
94
|
+
# integer :id
|
95
|
+
# string :admin_graphql_api_id
|
96
|
+
# integer :fulfillable_quantity
|
97
|
+
# string :fulfillment_service
|
98
|
+
# string :fulfillment_status
|
99
|
+
# boolean :gift_card
|
100
|
+
# integer :grams
|
101
|
+
# string :name
|
102
|
+
# string :price
|
103
|
+
# hash :price_set
|
104
|
+
# boolean :product_exists
|
105
|
+
# integer :product_id
|
106
|
+
# array :properties
|
107
|
+
# integer :quantity
|
108
|
+
# boolean :requires_shipping
|
109
|
+
# string :sku
|
110
|
+
# boolean :taxable
|
111
|
+
# string :title
|
112
|
+
# string :total_discount
|
113
|
+
# hash :total_discount_set
|
114
|
+
# integer :variant_id
|
115
|
+
# string :variant_inventory_management
|
116
|
+
# string :variant_title
|
117
|
+
# string :vendor
|
118
|
+
# array :tax_lines
|
119
|
+
# array :duties
|
120
|
+
# array :discount_allocations
|
121
|
+
|
122
|
+
|
123
|
+
# BG = {
|
124
|
+
# "consignments": [
|
125
|
+
# {
|
126
|
+
# "pickups": [],
|
127
|
+
# "shipping": [
|
128
|
+
# {
|
129
|
+
# "id": 3,
|
130
|
+
# "first_name": "Jane",
|
131
|
+
# "last_name": "Doe",
|
132
|
+
# "company": "",
|
133
|
+
# "street_1": "123 Main Street",
|
134
|
+
# "street_2": "",
|
135
|
+
# "city": "Austin",
|
136
|
+
# "zip": "78751",
|
137
|
+
# "country": "United States",
|
138
|
+
# "country_iso2": "US",
|
139
|
+
# "state": "Texas",
|
140
|
+
# "email": "oli@example.com",
|
141
|
+
# "phone": "",
|
142
|
+
# "form_fields": [],
|
143
|
+
# "line_items": [
|
144
|
+
# {
|
145
|
+
# "id": 3,
|
146
|
+
# "order_id": 102,
|
147
|
+
# "product_id": 88,
|
148
|
+
# "variant_id": 81,
|
149
|
+
# "order_pickup_method_id": 0,
|
150
|
+
# "order_address_id": 3,
|
151
|
+
# "name": "Chemex Coffeemaker",
|
152
|
+
# "name_customer": "Chemex Coffeemaker",
|
153
|
+
# "name_merchant": "Chemex Coffeemaker",
|
154
|
+
# "sku": "CC3C-SM",
|
155
|
+
# "upc": "",
|
156
|
+
# "type": "physical",
|
157
|
+
# "base_price": "83.3300",
|
158
|
+
# "price_ex_tax": "83.3300",
|
159
|
+
# "price_inc_tax": "83.3300",
|
160
|
+
# "price_tax": "0.0000",
|
161
|
+
# "base_total": "83.3300",
|
162
|
+
# "total_ex_tax": "83.3300",
|
163
|
+
# "total_inc_tax": "83.3300",
|
164
|
+
# "total_tax": "0.0000",
|
165
|
+
# "weight": "1.0000",
|
166
|
+
# "width": "0.0000",
|
167
|
+
# "height": "0.0000",
|
168
|
+
# "depth": "0.0000",
|
169
|
+
# "quantity": 1,
|
170
|
+
# "base_cost_price": "0.0000",
|
171
|
+
# "cost_price_inc_tax": "0.0000",
|
172
|
+
# "cost_price_ex_tax": "0.0000",
|
173
|
+
# "cost_price_tax": "0.0000",
|
174
|
+
# "is_refunded": false,
|
175
|
+
# "quantity_refunded": 0,
|
176
|
+
# "refund_amount": "0.0000",
|
177
|
+
# "return_id": 0,
|
178
|
+
# "wrapping_id": 0,
|
179
|
+
# "wrapping_name": "",
|
180
|
+
# "base_wrapping_cost": "0.0000",
|
181
|
+
# "wrapping_cost_ex_tax": "0.0000",
|
182
|
+
# "wrapping_cost_inc_tax": "0.0000",
|
183
|
+
# "wrapping_cost_tax": "0.0000",
|
184
|
+
# "wrapping_message": "",
|
185
|
+
# "quantity_shipped": 0,
|
186
|
+
# "event_name": null,
|
187
|
+
# "event_date": null,
|
188
|
+
# "fixed_shipping_cost": "0.0000",
|
189
|
+
# "ebay_item_id": "",
|
190
|
+
# "ebay_transaction_id": "",
|
191
|
+
# "option_set_id": 18,
|
192
|
+
# "parent_order_product_id": null,
|
193
|
+
# "is_bundled_product": false,
|
194
|
+
# "bin_picking_number": "0",
|
195
|
+
# "external_id": "",
|
196
|
+
# "fulfillment_source": "",
|
197
|
+
# "brand": "",
|
198
|
+
# "gift_certificate_id": null,
|
199
|
+
# "applied_discounts": [],
|
200
|
+
# "product_options": [
|
201
|
+
# {
|
202
|
+
# "id": 2,
|
203
|
+
# "option_id": 34,
|
204
|
+
# "order_product_id": 3,
|
205
|
+
# "product_option_id": 114,
|
206
|
+
# "display_name": "Size",
|
207
|
+
# "display_name_customer": "Size",
|
208
|
+
# "display_name_merchant": "Size",
|
209
|
+
# "display_value": "Small",
|
210
|
+
# "display_value_customer": "Small",
|
211
|
+
# "display_value_merchant": "Small",
|
212
|
+
# "value": "101",
|
213
|
+
# "type": "Multiple choice",
|
214
|
+
# "name": "Size1699441692-88",
|
215
|
+
# "display_style": "Dropdown"
|
216
|
+
# }
|
217
|
+
# ],
|
218
|
+
# "configurable_fields": [],
|
219
|
+
# "discounted_total_inc_tax": "83.3300"
|
220
|
+
# }
|
221
|
+
# ]
|
222
|
+
# }
|
223
|
+
# ],
|
224
|
+
# "items_total": 1,
|
225
|
+
# "items_shipped": 0,
|
226
|
+
# "shipping_method": "None",
|
227
|
+
# "base_cost": 0,
|
228
|
+
# "cost_ex_tax": 0,
|
229
|
+
# "cost_inc_tax": 0,
|
230
|
+
# "cost_tax": 0,
|
231
|
+
# "cost_tax_class_id": 0,
|
232
|
+
# "base_handling_cost": 0,
|
233
|
+
# "handling_cost_ex_tax": 0,
|
234
|
+
# "handling_cost_inc_tax": 0,
|
235
|
+
# "handling_cost_tax": 0,
|
236
|
+
# "handling_cost_tax_class_id": 0,
|
237
|
+
# "shipping_zone_id": 0,
|
238
|
+
# "shipping_zone_name": "",
|
239
|
+
# "shipping_quotes": {
|
240
|
+
# "url": "https://api.bigcommerce.com/stores/d0kmq3bory/v2/orders/102/consignments/shipping/3/shipping_quotes",
|
241
|
+
# "resource": "/orders/102/consignments/shipping/3/shipping_quotes"
|
242
|
+
# }
|
243
|
+
# }
|
244
|
+
# ]
|
245
|
+
# }
|
246
|
+
|
247
|
+
# Shopify = {
|
248
|
+
# "line_items": [
|
249
|
+
# {
|
250
|
+
# "id": 13120677806211,
|
251
|
+
# "admin_graphql_api_id": "gid://shopify/LineItem/13120677806211",
|
252
|
+
# "fulfillable_quantity": 1,
|
253
|
+
# "fulfillment_service": "manual",
|
254
|
+
# "fulfillment_status": null,
|
255
|
+
# "gift_card": false,
|
256
|
+
# "grams": 0,
|
257
|
+
# "name": "Winter Luggage - Sienna the longest name variant in the world",
|
258
|
+
# "price": "150.00",
|
259
|
+
# "price_set": {
|
260
|
+
# "shop_money": {
|
261
|
+
# "amount": "150.00",
|
262
|
+
# "currency_code": "GBP"
|
263
|
+
# },
|
264
|
+
# "presentment_money": {
|
265
|
+
# "amount": "150.00",
|
266
|
+
# "currency_code": "GBP"
|
267
|
+
# }
|
268
|
+
# },
|
269
|
+
# "product_exists": true,
|
270
|
+
# "product_id": 6610509627523,
|
271
|
+
# "properties": [],
|
272
|
+
# "quantity": 1,
|
273
|
+
# "requires_shipping": true,
|
274
|
+
# "sku": "skusku123",
|
275
|
+
# "taxable": true,
|
276
|
+
# "title": "Winter Luggage",
|
277
|
+
# "total_discount": "0.00",
|
278
|
+
# "total_discount_set": {
|
279
|
+
# "shop_money": {
|
280
|
+
# "amount": "0.00",
|
281
|
+
# "currency_code": "GBP"
|
282
|
+
# },
|
283
|
+
# "presentment_money": {
|
284
|
+
# "amount": "0.00",
|
285
|
+
# "currency_code": "GBP"
|
286
|
+
# }
|
287
|
+
# },
|
288
|
+
# "variant_id": 39428269408387,
|
289
|
+
# "variant_inventory_management": "shopify",
|
290
|
+
# "variant_title": "Sienna the longest name variant in the world",
|
291
|
+
# "vendor": "PreProduct Test",
|
292
|
+
# "tax_lines": [],
|
293
|
+
# "duties": [],
|
294
|
+
# "discount_allocations": []
|
295
|
+
# }
|
296
|
+
# ]
|
297
|
+
# }
|
data/lib/e_plat/mapping.rb
CHANGED
@@ -5,11 +5,11 @@ module EPlat
|
|
5
5
|
|
6
6
|
class << self
|
7
7
|
|
8
|
-
def new_instance(specifc_mapping:)
|
8
|
+
def new_instance(specifc_mapping:, resource: nil)
|
9
9
|
if Object.const_defined?(specifc_mapping)
|
10
|
-
mapping = specifc_mapping.constantize.new
|
10
|
+
mapping = specifc_mapping.constantize.new(resource)
|
11
11
|
else
|
12
|
-
mapping = EPlat::Mapping::Base.new
|
12
|
+
mapping = EPlat::Mapping::Base.new(resource)
|
13
13
|
end
|
14
14
|
end
|
15
15
|
|
@@ -1,10 +1,11 @@
|
|
1
1
|
module EPlat
|
2
2
|
class AttributeInterface
|
3
|
-
attr_accessor :
|
3
|
+
attr_accessor :klass, :keys
|
4
4
|
|
5
|
-
def initialize(
|
6
|
-
@
|
7
|
-
|
5
|
+
def initialize(klass, keys:)
|
6
|
+
@klass, @keys = klass, keys
|
7
|
+
|
8
|
+
add_to_instance! if keys.present?
|
8
9
|
end
|
9
10
|
|
10
11
|
def inspect
|
@@ -12,15 +13,15 @@ module EPlat
|
|
12
13
|
end
|
13
14
|
|
14
15
|
def entries
|
15
|
-
keys.map{|k| {k =>
|
16
|
+
keys.map{|k| {k => klass.send(k)} }.inject(&:merge)
|
16
17
|
end
|
17
18
|
|
18
19
|
define_method :[] do |key|
|
19
|
-
|
20
|
+
klass.attributes[key]
|
20
21
|
end
|
21
22
|
|
22
23
|
define_method :[]= do |key, value|
|
23
|
-
|
24
|
+
klass.attributes[key] = value
|
24
25
|
end
|
25
26
|
|
26
27
|
def include?(value)
|
@@ -34,27 +35,26 @@ module EPlat
|
|
34
35
|
|
35
36
|
private
|
36
37
|
|
37
|
-
def
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
end
|
38
|
+
def add_to_instance!
|
39
|
+
meta_programming_string =
|
40
|
+
keys.map do |key|
|
41
|
+
<<-STRING
|
42
|
+
def #{ key }
|
43
|
+
self.attributes['#{key}']
|
44
|
+
end
|
45
|
+
|
46
|
+
def #{key}=(value)
|
47
|
+
self.attributes['#{key}'] = value
|
48
|
+
end
|
49
|
+
|
50
|
+
def #{ key }?
|
51
|
+
ActiveModel::Type::Boolean.new.cast send '#{key}'
|
52
|
+
end
|
53
|
+
STRING
|
54
|
+
end.join("\n")
|
55
|
+
|
56
|
+
klass.instance_eval { eval meta_programming_string }
|
57
|
+
end
|
58
58
|
|
59
59
|
end
|
60
60
|
end
|
data/lib/e_plat/resource/base.rb
CHANGED
@@ -2,79 +2,151 @@
|
|
2
2
|
|
3
3
|
module EPlat
|
4
4
|
class Base < ActiveResource::Base
|
5
|
+
include Concerns::OverwriteRequestMethods, Concerns::OverwriteInstanceMethods
|
6
|
+
include Concerns::Aliases, Concerns::Dirty
|
5
7
|
|
8
|
+
self.connection_class = EPlat::Connection
|
9
|
+
self.collection_parser = EPlat::Collection
|
10
|
+
self.site = "/" # this is overwritten below in initialize_singleton! when EPlat::Session is initialized
|
11
|
+
add_response_method :full_response
|
12
|
+
|
6
13
|
class << self
|
7
|
-
include
|
8
|
-
|
9
|
-
|
14
|
+
include Countable
|
15
|
+
|
16
|
+
attr_accessor :read_only
|
17
|
+
|
18
|
+
threadsafe_attribute :_headers, :_connection, :_user, :_password, :_bearer_token, :_site, :_proxy, # active resource
|
19
|
+
:mapping, :include_root_in_json, :include_format_in_path # e_plat specific
|
10
20
|
|
11
21
|
def initialize_singleton!
|
12
|
-
self.
|
13
|
-
|
14
|
-
self.site = client.base_url
|
15
|
-
self.prefix = client.url_prefix
|
22
|
+
self.site = client.base_url # .site is an ActiveResource method that uses the threadsafe _site attribute underneath
|
23
|
+
self.prefix = client.url_prefix(klass: self) # this is overwritten below in prefix= for threadsafety
|
16
24
|
|
17
25
|
self.timeout = 5
|
18
|
-
self.include_format_in_path =
|
26
|
+
self.include_format_in_path = client.include_format_in_path?
|
19
27
|
self.mapping = mapping_instance
|
20
28
|
|
21
29
|
client.platform_headers.each {|name, value| self.headers[name] = value}
|
22
30
|
end
|
23
|
-
|
24
|
-
def
|
25
|
-
|
31
|
+
|
32
|
+
def client
|
33
|
+
Current.e_plat_session
|
34
|
+
end
|
35
|
+
|
36
|
+
|
37
|
+
# monkey patch prefix= so we can add thread-local value to the generated prefix_source() method
|
38
|
+
def prefix=(value = "/")
|
39
|
+
# Replace :placeholders with '#{embedded options[:lookups]}'
|
40
|
+
prefix_call = value.gsub(/:\w+/) { |key| "\#{URI::DEFAULT_PARSER.escape options[#{key}].to_s}" }
|
41
|
+
|
42
|
+
# Clear prefix parameters in case they have been cached
|
43
|
+
@prefix_parameters = nil
|
44
|
+
|
45
|
+
silence_warnings do
|
46
|
+
# Redefine the new methods.
|
47
|
+
instance_eval <<-RUBY_EVAL, __FILE__, __LINE__ + 1
|
48
|
+
def prefix_source()
|
49
|
+
client.url_prefix(klass: self) || "#{value}"
|
50
|
+
end
|
51
|
+
def prefix(options={}) "#{prefix_call}" end
|
52
|
+
RUBY_EVAL
|
53
|
+
end
|
54
|
+
rescue Exception => e
|
55
|
+
logger.error "Couldn't set prefix: #{e}\n #{code}" if logger
|
56
|
+
raise
|
57
|
+
end
|
58
|
+
|
59
|
+
def exclude_from_json(read_only)
|
60
|
+
self.read_only = read_only
|
26
61
|
end
|
62
|
+
|
27
63
|
|
28
64
|
private
|
29
65
|
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
end
|
66
|
+
def mapping_instance
|
67
|
+
mapping_class_name = "EPlat::Mapping::#{ client.platform.capitalize }::V#{ client.api_version.camelize }::#{ element_name.classify }"
|
68
|
+
|
69
|
+
EPlat::Mapping.new_instance(specifc_mapping: mapping_class_name, resource: nil)
|
70
|
+
end
|
36
71
|
|
37
72
|
end
|
38
73
|
|
39
|
-
|
40
|
-
include Dry::Effects.State(:e_plat_session)
|
41
|
-
include Concerns::Aliases, Concerns::OverwriteInstanceMethods
|
42
|
-
|
43
|
-
attr_accessor :client, :mapping, :mapped_attributes
|
74
|
+
attr_accessor :mapping, :mapped_attributes
|
44
75
|
|
45
76
|
def initialize(attributes = {}, persisted = false)
|
46
|
-
self.client = e_plat_session
|
47
77
|
site = client.base_url
|
48
|
-
self.mapping = mapping_instance
|
49
78
|
ActiveResource::Base.include_root_in_json = client.shopify? && top_level_resource?
|
50
79
|
|
51
80
|
super
|
81
|
+
|
82
|
+
self.mapping = mapping_instance
|
52
83
|
|
53
|
-
|
54
|
-
|
84
|
+
@mapped_attributes = ensure_e_plat_attributes!
|
85
|
+
ensure_native_attributes!
|
86
|
+
add_aliases!(mapping.native_attribute_aliases, type_schema || {})
|
55
87
|
end
|
56
|
-
|
88
|
+
|
89
|
+
def client
|
90
|
+
Current.e_plat_session
|
91
|
+
end
|
92
|
+
|
57
93
|
def mapped?(attribute)
|
58
94
|
mapped_attributes.include? attribute.to_s
|
59
95
|
end
|
60
96
|
|
61
97
|
def native_keys
|
62
|
-
|
98
|
+
if client.shopify?
|
99
|
+
schema.keys # EPlat uses Shopify's schema, so keys are always native
|
100
|
+
elsif mapping.class.to_s != EPlat::Mapping::Base && @mapping.native_attributes.present?
|
101
|
+
@mapping.native_attributes.presence
|
102
|
+
else
|
103
|
+
attributes.keys
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
def read_only?
|
108
|
+
!!self.class.read_only
|
109
|
+
end
|
110
|
+
|
111
|
+
def headers
|
112
|
+
full_response&.each_header&.to_h || {}
|
113
|
+
end
|
114
|
+
|
115
|
+
def include_root_in_json
|
116
|
+
return false unless client.shopify?
|
117
|
+
|
118
|
+
top_level_resource?
|
63
119
|
end
|
64
120
|
|
121
|
+
|
65
122
|
private
|
123
|
+
|
124
|
+
def ensure_e_plat_attributes!
|
125
|
+
AttributeInterface.new(self, keys: mappable_keys)
|
126
|
+
end
|
127
|
+
|
128
|
+
def ensure_native_attributes!
|
129
|
+
return if client.shopify? # EPlat uses Shopify's schema
|
130
|
+
|
131
|
+
AttributeInterface.new(self, keys: native_keys)
|
132
|
+
end
|
66
133
|
|
67
134
|
def mapping_instance
|
68
135
|
class_constant_string = self.class.to_s.gsub("EPlat::", "")
|
69
136
|
mapping_class_name = "EPlat::Mapping::#{ client.platform.capitalize }::V#{ client.api_version.camelize }::#{ class_constant_string }"
|
70
|
-
|
71
|
-
EPlat::Mapping.new_instance(specifc_mapping: mapping_class_name)
|
137
|
+
|
138
|
+
EPlat::Mapping.new_instance(specifc_mapping: mapping_class_name, resource: self)
|
72
139
|
end
|
73
140
|
|
74
141
|
def mappable_keys
|
75
142
|
mappable_keys = mapping.mappable_keys
|
76
143
|
(mappable_keys == :all) ? schema.keys : mappable_keys
|
77
144
|
end
|
145
|
+
|
146
|
+
def type_schema
|
147
|
+
return unless schema.present? && schema.values.any?{|value| value == "string" or value == "hash" }
|
148
|
+
schema
|
149
|
+
end
|
78
150
|
|
79
151
|
def type_check!(schema)
|
80
152
|
schema.each{|name, type| type_attr!(name, type) }
|
@@ -98,10 +170,11 @@ module EPlat
|
|
98
170
|
end
|
99
171
|
|
100
172
|
def top_level_resource?
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
173
|
+
self.class.name.split("::").count <= 2
|
174
|
+
end
|
175
|
+
|
176
|
+
def element_name
|
177
|
+
self.class.element_name
|
105
178
|
end
|
106
179
|
|
107
180
|
end
|
@@ -109,37 +182,3 @@ module EPlat
|
|
109
182
|
|
110
183
|
end
|
111
184
|
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
###### api call methods
|
119
|
-
|
120
|
-
### create new entry
|
121
|
-
# product = EPlat::Product.new(:title => 't-shirt')
|
122
|
-
# t-shirt.save
|
123
|
-
# or... EPlat::Product.create(:title => 't-shirt')
|
124
|
-
# new_product = product.dup #duplicates entry without saving
|
125
|
-
|
126
|
-
### delete record
|
127
|
-
# EPlat::Product.delete(params[:id])
|
128
|
-
# EPlat::Product.find(my_id).destroy
|
129
|
-
|
130
|
-
### save record
|
131
|
-
# product = EPlat::Product.new(:title => 't-shirt')
|
132
|
-
# product.save
|
133
|
-
|
134
|
-
### get records
|
135
|
-
# EPlat::Product.find(1) # => GET /people/1.json (or EPlat::Product.first(args)) (or EPlat::Product.last(args))
|
136
|
-
# EPlat::Product.find(:all) # => GET /people.json
|
137
|
-
# EPlat::Product.find(:all, :params => { :title => "tshirt" }) # => GET /product.json?title=tshirt
|
138
|
-
# EPlat::Product.find(:one, :from => :leader) # => GET /product/leader.json
|
139
|
-
# EPlat::Product.find(:one, :from => "/companies/1/manager.json") # => GET /companies/1/manager.json
|
140
|
-
|
141
|
-
|
142
|
-
#### options
|
143
|
-
# prefix_options #for nested URLs Comment.collection_path(:post_id => 5) # => /posts/5/comments.json
|
144
|
-
# query_options #to add to params ?x=y
|
145
|
-
# instance.known_attributes #to return mix of schema and native attributes
|