conexa 0.0.9 → 0.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/CHANGELOG.md +37 -1
- data/Gemfile.lock +1 -1
- data/README.md +79 -73
- data/README_pt-BR.md +28 -19
- data/REFERENCE.md +22 -12
- data/lib/conexa/authenticator.rb +2 -0
- data/lib/conexa/configuration.rb +2 -0
- data/lib/conexa/core_ext.rb +11 -6
- data/lib/conexa/errors.rb +5 -3
- data/lib/conexa/model.rb +44 -28
- data/lib/conexa/object.rb +6 -16
- data/lib/conexa/{order_commom.rb → order_common.rb} +5 -5
- data/lib/conexa/request.rb +9 -8
- data/lib/conexa/resources/bill.rb +3 -1
- data/lib/conexa/resources/company.rb +2 -0
- data/lib/conexa/resources/credit_card.rb +2 -0
- data/lib/conexa/resources/invoicing_method.rb +2 -0
- data/lib/conexa/resources/legal_person.rb +2 -0
- data/lib/conexa/resources/pagination.rb +2 -0
- data/lib/conexa/resources/person.rb +2 -0
- data/lib/conexa/resources/plan.rb +2 -0
- data/lib/conexa/resources/product.rb +2 -0
- data/lib/conexa/resources/recurring_sale.rb +2 -0
- data/lib/conexa/resources/result.rb +32 -5
- data/lib/conexa/token_manager.rb +3 -1
- data/lib/conexa/util.rb +37 -50
- data/lib/conexa/version.rb +1 -1
- data/lib/conexa.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 76a95e870fc63f79b15b5227f1f0a10d94471efe573662dc626e42e57cf77b82
|
|
4
|
+
data.tar.gz: 92fce7222c5b9adad92e6524e6dbfb3466bc1282a81768c5872922af37d2085b
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 4071bc748f2855c39eb48e7360bf4d519f0502d898ca7e915c88c41115bb85422766a2e0274d9ab39ac032de69507dd2275b5fa976de26b8dc586846f3089814
|
|
7
|
+
data.tar.gz: 2962227ceb63eb324be8289502669995d4ac4d1136fd18570f972024b0774e0ff874c5c71d7fca8c296cd882850284415d8ce784312d1867d7471b3783ec79d3
|
data/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,41 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [0.1.0] - 2026-03-31
|
|
11
|
+
|
|
12
|
+
### Added
|
|
13
|
+
- `Result#next_page` — automatically fetches the next page preserving original filter params
|
|
14
|
+
- `Result#has_next?` — convenience method to check if more pages are available
|
|
15
|
+
- Pagination migration guide added to README (EN/PT-BR) and REFERENCE.md
|
|
16
|
+
- Validation for `limit` (must be positive integer) and `offset` (must be non-negative integer) parameters
|
|
17
|
+
- `frozen_string_literal: true` pragma added to all Ruby source files
|
|
18
|
+
- ActiveSupport compatibility guard for `blank?`/`present?` monkey-patches
|
|
19
|
+
- `respond_to_missing?` implemented in `ConexaObject` and `Result` (Ruby best practice)
|
|
20
|
+
- Integration tests for all new API v2 resources (24 specs)
|
|
21
|
+
- Unit tests for pagination validation and `class_name` camelCase preservation (6 specs)
|
|
22
|
+
- Total: 502 specs
|
|
23
|
+
|
|
24
|
+
### Changed
|
|
25
|
+
- **Breaking**: Default pagination is now `limit: 100, offset: 0` (was `page: 1, size: 100`)
|
|
26
|
+
- Calling `.all` or `.find_by` without pagination params now uses the new model
|
|
27
|
+
- Legacy `page`/`size` is only used when explicitly passed (emits deprecation warning)
|
|
28
|
+
- `Model.all` simplified — delegates directly to `find_by` without double param extraction
|
|
29
|
+
- `Model.class_name` now returns proper lowerCamelCase (e.g. `recurringSale` instead of `recurringsale`)
|
|
30
|
+
- `OrderCommom` renamed to `OrderCommon` (backwards-compatible alias kept)
|
|
31
|
+
- `Bill#save` now raises `NoMethodError` with descriptive message
|
|
32
|
+
- README updated: all examples now use correct method names (`.all`, `.find`, `.destroy`)
|
|
33
|
+
- README error handling section rewritten with actual exception classes
|
|
34
|
+
|
|
35
|
+
### Fixed
|
|
36
|
+
- **Concurrency bug**: `DEFAULT_HEADERS` constant was mutated on every request; now uses `.dup`
|
|
37
|
+
- **Boolean false bug**: `Result#method_missing` skipped `false` attribute values due to `||` operator
|
|
38
|
+
- **ValidationError crash**: undefined variable `error` in block scope — fixed to use `msg`
|
|
39
|
+
- **TokenManager typo**: `ShiConexa` → `Conexa` in credentials handling
|
|
40
|
+
- **Singularize**: `SINGULARS` patterns were stored as strings, never used as regex — rewritten with proper `Regexp` objects
|
|
41
|
+
- **Deep copy**: `Result#next_page` now uses `Marshal.load(Marshal.dump(...))` to prevent param mutation between pages
|
|
42
|
+
- Stray `-` character removed from `util.rb`
|
|
43
|
+
- Removed dead code: `Hash#except_nested` monkey-patch, commented-out `to_s` method
|
|
44
|
+
|
|
10
45
|
## [0.0.9] - 2026-03-30
|
|
11
46
|
|
|
12
47
|
### Added
|
|
@@ -87,7 +122,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
87
122
|
- Charge with settle and PIX methods
|
|
88
123
|
- Pagination support
|
|
89
124
|
|
|
90
|
-
[Unreleased]: https://github.com/guilhermegazzinelli/conexa-ruby/compare/v0.0
|
|
125
|
+
[Unreleased]: https://github.com/guilhermegazzinelli/conexa-ruby/compare/v0.1.0...HEAD
|
|
126
|
+
[0.1.0]: https://github.com/guilhermegazzinelli/conexa-ruby/compare/v0.0.9...v0.1.0
|
|
91
127
|
[0.0.9]: https://github.com/guilhermegazzinelli/conexa-ruby/compare/v0.0.8...v0.0.9
|
|
92
128
|
[0.0.8]: https://github.com/guilhermegazzinelli/conexa-ruby/compare/v0.0.7...v0.0.8
|
|
93
129
|
[0.0.7]: https://github.com/guilhermegazzinelli/conexa-ruby/compare/v0.0.6...v0.0.7
|
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
|
@@ -46,13 +46,13 @@ Conexa.configure do |config|
|
|
|
46
46
|
end
|
|
47
47
|
|
|
48
48
|
# List customers
|
|
49
|
-
customers = Conexa::Customer.
|
|
49
|
+
customers = Conexa::Customer.all
|
|
50
50
|
customers.data.each do |customer|
|
|
51
51
|
puts "#{customer.customer_id}: #{customer.name}"
|
|
52
52
|
end
|
|
53
53
|
|
|
54
54
|
# Get a specific customer
|
|
55
|
-
customer = Conexa::Customer.
|
|
55
|
+
customer = Conexa::Customer.find(127)
|
|
56
56
|
puts customer.name
|
|
57
57
|
puts customer.address.city
|
|
58
58
|
```
|
|
@@ -110,7 +110,7 @@ customer = Conexa::Customer.create(
|
|
|
110
110
|
)
|
|
111
111
|
|
|
112
112
|
# Retrieve customer
|
|
113
|
-
customer = Conexa::Customer.
|
|
113
|
+
customer = Conexa::Customer.find(127)
|
|
114
114
|
customer.name # => "Empresa ABC Ltda"
|
|
115
115
|
customer.company_id # => 3
|
|
116
116
|
customer.is_active # => true
|
|
@@ -118,10 +118,13 @@ customer.address.city # => "Campinas"
|
|
|
118
118
|
customer.legal_person['cnpj'] # => "99.557.155/0001-90"
|
|
119
119
|
|
|
120
120
|
# Update customer
|
|
121
|
-
Conexa::Customer.
|
|
121
|
+
customer = Conexa::Customer.find(127)
|
|
122
|
+
customer.name = 'New Name'
|
|
123
|
+
customer.cell_number = '11888887777'
|
|
124
|
+
customer.save
|
|
122
125
|
|
|
123
126
|
# List customers with filters (new pagination)
|
|
124
|
-
customers = Conexa::Customer.
|
|
127
|
+
customers = Conexa::Customer.all(
|
|
125
128
|
company_id: [3],
|
|
126
129
|
is_active: true,
|
|
127
130
|
limit: 20
|
|
@@ -152,7 +155,7 @@ contract = Conexa::Contract.create_with_products(
|
|
|
152
155
|
)
|
|
153
156
|
|
|
154
157
|
# Retrieve contract
|
|
155
|
-
contract = Conexa::Contract.
|
|
158
|
+
contract = Conexa::Contract.find(456)
|
|
156
159
|
|
|
157
160
|
# Cancel contract
|
|
158
161
|
Conexa::Contract.cancel(456, cancel_date: '2024-12-31')
|
|
@@ -174,13 +177,13 @@ sale = Conexa::Sale.create(
|
|
|
174
177
|
puts sale.id # => 188481
|
|
175
178
|
|
|
176
179
|
# Retrieve sale
|
|
177
|
-
sale = Conexa::Sale.
|
|
180
|
+
sale = Conexa::Sale.find(188510)
|
|
178
181
|
sale.status # => "notBilled"
|
|
179
182
|
sale.amount # => 80.99
|
|
180
183
|
sale.discount_value # => 69.21
|
|
181
184
|
|
|
182
185
|
# List sales
|
|
183
|
-
sales = Conexa::Sale.
|
|
186
|
+
sales = Conexa::Sale.all(
|
|
184
187
|
customer_id: [450, 216],
|
|
185
188
|
status: 'notBilled',
|
|
186
189
|
date_from: '2024-01-01',
|
|
@@ -190,10 +193,13 @@ sales = Conexa::Sale.list(
|
|
|
190
193
|
)
|
|
191
194
|
|
|
192
195
|
# Update sale
|
|
193
|
-
Conexa::Sale.
|
|
196
|
+
sale = Conexa::Sale.find(188510)
|
|
197
|
+
sale.quantity = 2
|
|
198
|
+
sale.amount = 150.00
|
|
199
|
+
sale.save
|
|
194
200
|
|
|
195
201
|
# Delete sale (only if not billed)
|
|
196
|
-
Conexa::Sale.
|
|
202
|
+
Conexa::Sale.destroy(188510)
|
|
197
203
|
```
|
|
198
204
|
|
|
199
205
|
### Recurring Sale
|
|
@@ -208,20 +214,20 @@ recurring = Conexa::RecurringSale.create(
|
|
|
208
214
|
)
|
|
209
215
|
|
|
210
216
|
# List recurring sales for a contract
|
|
211
|
-
Conexa::RecurringSale.
|
|
217
|
+
Conexa::RecurringSale.all(contract_id: 456)
|
|
212
218
|
```
|
|
213
219
|
|
|
214
220
|
### Charge
|
|
215
221
|
|
|
216
222
|
```ruby
|
|
217
223
|
# Retrieve charge
|
|
218
|
-
charge = Conexa::Charge.
|
|
224
|
+
charge = Conexa::Charge.find(789)
|
|
219
225
|
charge.status # => "paid"
|
|
220
226
|
charge.amount # => 299.90
|
|
221
227
|
charge.due_date # => "2024-02-10"
|
|
222
228
|
|
|
223
229
|
# List charges
|
|
224
|
-
charges = Conexa::Charge.
|
|
230
|
+
charges = Conexa::Charge.all(
|
|
225
231
|
customer_id: [127],
|
|
226
232
|
status: 'pending',
|
|
227
233
|
due_date_from: '2024-01-01',
|
|
@@ -239,10 +245,10 @@ Conexa::Charge.send_email(789)
|
|
|
239
245
|
|
|
240
246
|
```ruby
|
|
241
247
|
# Retrieve bill
|
|
242
|
-
bill = Conexa::Bill.
|
|
248
|
+
bill = Conexa::Bill.find(101)
|
|
243
249
|
|
|
244
250
|
# List bills
|
|
245
|
-
bills = Conexa::Bill.
|
|
251
|
+
bills = Conexa::Bill.all(
|
|
246
252
|
customer_id: [127],
|
|
247
253
|
page: 1,
|
|
248
254
|
size: 50
|
|
@@ -253,10 +259,10 @@ bills = Conexa::Bill.list(
|
|
|
253
259
|
|
|
254
260
|
```ruby
|
|
255
261
|
# List plans
|
|
256
|
-
plans = Conexa::Plan.
|
|
262
|
+
plans = Conexa::Plan.all(company_id: [3])
|
|
257
263
|
|
|
258
264
|
# Retrieve plan
|
|
259
|
-
plan = Conexa::Plan.
|
|
265
|
+
plan = Conexa::Plan.find(5)
|
|
260
266
|
plan.name # => "Plano Básico"
|
|
261
267
|
plan.price # => 99.90
|
|
262
268
|
```
|
|
@@ -265,66 +271,66 @@ plan.price # => 99.90
|
|
|
265
271
|
|
|
266
272
|
```ruby
|
|
267
273
|
# List products
|
|
268
|
-
products = Conexa::Product.
|
|
274
|
+
products = Conexa::Product.all(company_id: [3], limit: 50)
|
|
269
275
|
|
|
270
276
|
# Retrieve product
|
|
271
|
-
product = Conexa::Product.
|
|
277
|
+
product = Conexa::Product.find(101)
|
|
272
278
|
|
|
273
279
|
# Create product
|
|
274
280
|
product = Conexa::Product.create(name: 'Novo Produto', company_id: 3)
|
|
275
281
|
|
|
276
282
|
# Delete product
|
|
277
|
-
Conexa::Product.
|
|
283
|
+
Conexa::Product.destroy(101)
|
|
278
284
|
```
|
|
279
285
|
|
|
280
286
|
### Receiving Method
|
|
281
287
|
|
|
282
288
|
```ruby
|
|
283
|
-
methods = Conexa::ReceivingMethod.
|
|
284
|
-
method = Conexa::ReceivingMethod.
|
|
289
|
+
methods = Conexa::ReceivingMethod.all(limit: 50)
|
|
290
|
+
method = Conexa::ReceivingMethod.find(11)
|
|
285
291
|
method.name # => "Cartão de Crédito"
|
|
286
292
|
```
|
|
287
293
|
|
|
288
294
|
### Payment Method
|
|
289
295
|
|
|
290
296
|
```ruby
|
|
291
|
-
methods = Conexa::PaymentMethod.
|
|
292
|
-
method = Conexa::PaymentMethod.
|
|
297
|
+
methods = Conexa::PaymentMethod.all(limit: 50)
|
|
298
|
+
method = Conexa::PaymentMethod.find(2)
|
|
293
299
|
```
|
|
294
300
|
|
|
295
301
|
### Bill Category / Subcategory
|
|
296
302
|
|
|
297
303
|
```ruby
|
|
298
|
-
categories = Conexa::BillCategory.
|
|
299
|
-
subcategories = Conexa::BillSubcategory.
|
|
304
|
+
categories = Conexa::BillCategory.all(limit: 50)
|
|
305
|
+
subcategories = Conexa::BillSubcategory.all(limit: 50)
|
|
300
306
|
```
|
|
301
307
|
|
|
302
308
|
### Cost Center
|
|
303
309
|
|
|
304
310
|
```ruby
|
|
305
|
-
centers = Conexa::CostCenter.
|
|
306
|
-
center = Conexa::CostCenter.
|
|
311
|
+
centers = Conexa::CostCenter.all(limit: 50)
|
|
312
|
+
center = Conexa::CostCenter.find(11)
|
|
307
313
|
```
|
|
308
314
|
|
|
309
315
|
### Account
|
|
310
316
|
|
|
311
317
|
```ruby
|
|
312
|
-
accounts = Conexa::Account.
|
|
313
|
-
account = Conexa::Account.
|
|
318
|
+
accounts = Conexa::Account.all(limit: 50)
|
|
319
|
+
account = Conexa::Account.find(23)
|
|
314
320
|
```
|
|
315
321
|
|
|
316
322
|
### Service Category
|
|
317
323
|
|
|
318
324
|
```ruby
|
|
319
|
-
categories = Conexa::ServiceCategory.
|
|
320
|
-
category = Conexa::ServiceCategory.
|
|
325
|
+
categories = Conexa::ServiceCategory.all(limit: 50)
|
|
326
|
+
category = Conexa::ServiceCategory.find(1)
|
|
321
327
|
```
|
|
322
328
|
|
|
323
329
|
### Room Booking
|
|
324
330
|
|
|
325
331
|
```ruby
|
|
326
332
|
# List bookings
|
|
327
|
-
bookings = Conexa::RoomBooking.
|
|
333
|
+
bookings = Conexa::RoomBooking.all(limit: 20)
|
|
328
334
|
|
|
329
335
|
# Create booking
|
|
330
336
|
booking = Conexa::RoomBooking.create(room_id: 5, customer_id: 127)
|
|
@@ -350,20 +356,20 @@ card = Conexa::CreditCard.create(
|
|
|
350
356
|
)
|
|
351
357
|
|
|
352
358
|
# List customer's cards
|
|
353
|
-
cards = Conexa::CreditCard.
|
|
359
|
+
cards = Conexa::CreditCard.all(customer_id: 127)
|
|
354
360
|
|
|
355
361
|
# Delete card
|
|
356
|
-
Conexa::CreditCard.
|
|
362
|
+
Conexa::CreditCard.destroy(card_id)
|
|
357
363
|
```
|
|
358
364
|
|
|
359
365
|
### Company (Unit)
|
|
360
366
|
|
|
361
367
|
```ruby
|
|
362
368
|
# List companies/units
|
|
363
|
-
companies = Conexa::Company.
|
|
369
|
+
companies = Conexa::Company.all
|
|
364
370
|
|
|
365
371
|
# Retrieve company
|
|
366
|
-
company = Conexa::Company.
|
|
372
|
+
company = Conexa::Company.find(3)
|
|
367
373
|
company.name # => "Matriz"
|
|
368
374
|
company.document # => "12.345.678/0001-90"
|
|
369
375
|
```
|
|
@@ -373,19 +379,27 @@ company.document # => "12.345.678/0001-90"
|
|
|
373
379
|
### New Pagination (recommended) — `limit`/`offset`/`hasNext`
|
|
374
380
|
|
|
375
381
|
```ruby
|
|
376
|
-
result = Conexa::Customer.
|
|
382
|
+
result = Conexa::Customer.all(limit: 50)
|
|
377
383
|
|
|
378
384
|
result.data # Array of customers
|
|
379
385
|
result.pagination.limit # => 50
|
|
380
386
|
result.pagination.offset # => 0
|
|
381
|
-
result.
|
|
387
|
+
result.has_next? # => true/false
|
|
382
388
|
|
|
383
|
-
# Iterate through all pages
|
|
389
|
+
# Iterate through all pages using next_page
|
|
390
|
+
result = Conexa::Customer.all(limit: 50)
|
|
391
|
+
loop do
|
|
392
|
+
result.data.each { |customer| process(customer) }
|
|
393
|
+
break unless result.has_next?
|
|
394
|
+
result = result.next_page
|
|
395
|
+
end
|
|
396
|
+
|
|
397
|
+
# Or manually with offset
|
|
384
398
|
offset = 0
|
|
385
399
|
loop do
|
|
386
|
-
result = Conexa::Customer.
|
|
400
|
+
result = Conexa::Customer.all(limit: 50, offset: offset)
|
|
387
401
|
result.data.each { |customer| process(customer) }
|
|
388
|
-
break unless result.
|
|
402
|
+
break unless result.has_next?
|
|
389
403
|
offset += 50
|
|
390
404
|
end
|
|
391
405
|
```
|
|
@@ -394,7 +408,7 @@ end
|
|
|
394
408
|
|
|
395
409
|
```ruby
|
|
396
410
|
# Still works but emits a deprecation warning
|
|
397
|
-
result = Conexa::Customer.
|
|
411
|
+
result = Conexa::Customer.all(page: 1, size: 20)
|
|
398
412
|
result.pagination.current_page # => 1
|
|
399
413
|
result.pagination.total_pages # => 10
|
|
400
414
|
```
|
|
@@ -407,12 +421,12 @@ The legacy `page`/`size` pagination is deprecated and will be removed on **2026-
|
|
|
407
421
|
|
|
408
422
|
```ruby
|
|
409
423
|
# BEFORE (legacy — deprecated)
|
|
410
|
-
result = Conexa::Customer.
|
|
411
|
-
result = Conexa::Customer.
|
|
424
|
+
result = Conexa::Customer.all(page: 1, size: 50)
|
|
425
|
+
result = Conexa::Customer.all(page: 2, size: 50)
|
|
412
426
|
|
|
413
427
|
# AFTER (new)
|
|
414
|
-
result = Conexa::Customer.
|
|
415
|
-
result = Conexa::Customer.
|
|
428
|
+
result = Conexa::Customer.all(limit: 50) # offset defaults to 0
|
|
429
|
+
result = Conexa::Customer.all(limit: 50, offset: 50) # second page
|
|
416
430
|
```
|
|
417
431
|
|
|
418
432
|
**Conversion formula:** `offset = (page - 1) * size`
|
|
@@ -436,19 +450,18 @@ result.pagination.has_next # => true/false
|
|
|
436
450
|
# BEFORE (legacy)
|
|
437
451
|
page = 1
|
|
438
452
|
loop do
|
|
439
|
-
result = Conexa::Customer.
|
|
453
|
+
result = Conexa::Customer.all(page: page, size: 100)
|
|
440
454
|
break if result.empty?
|
|
441
455
|
result.data.each { |c| process(c) }
|
|
442
456
|
page += 1
|
|
443
457
|
end
|
|
444
458
|
|
|
445
|
-
# AFTER (new)
|
|
446
|
-
|
|
459
|
+
# AFTER (new — using next_page)
|
|
460
|
+
result = Conexa::Customer.all(limit: 100)
|
|
447
461
|
loop do
|
|
448
|
-
result = Conexa::Customer.list(limit: 100, offset: offset)
|
|
449
462
|
result.data.each { |c| process(c) }
|
|
450
|
-
break unless result.
|
|
451
|
-
|
|
463
|
+
break unless result.has_next?
|
|
464
|
+
result = result.next_page
|
|
452
465
|
end
|
|
453
466
|
```
|
|
454
467
|
|
|
@@ -481,29 +494,22 @@ begin
|
|
|
481
494
|
customer = Conexa::Customer.create(name: '')
|
|
482
495
|
rescue Conexa::ValidationError => e
|
|
483
496
|
# Field validation errors (400)
|
|
484
|
-
e.errors.each do |error|
|
|
485
|
-
puts "#{error['field']}: #{error['messages'].join(', ')}"
|
|
486
|
-
end
|
|
487
|
-
rescue Conexa::AuthenticationError => e
|
|
488
|
-
# Authentication required (401)
|
|
489
497
|
puts e.message
|
|
490
|
-
rescue Conexa::
|
|
491
|
-
# Not authorized (403)
|
|
492
|
-
puts e.message
|
|
493
|
-
rescue Conexa::NotFoundError => e
|
|
498
|
+
rescue Conexa::NotFound => e
|
|
494
499
|
# Resource not found (404)
|
|
495
500
|
puts e.message
|
|
496
|
-
rescue Conexa::
|
|
497
|
-
#
|
|
498
|
-
e.
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
501
|
+
rescue Conexa::ResponseError => e
|
|
502
|
+
# API response error (4xx/5xx)
|
|
503
|
+
puts e.message
|
|
504
|
+
rescue Conexa::RequestError => e
|
|
505
|
+
# Request-level error (invalid params, etc.)
|
|
506
|
+
puts e.message
|
|
507
|
+
rescue Conexa::ConnectionError => e
|
|
508
|
+
# Network/connection error
|
|
509
|
+
puts e.message
|
|
510
|
+
rescue Conexa::ConexaError => e
|
|
511
|
+
# Generic Conexa error (catch-all)
|
|
512
|
+
puts e.message
|
|
507
513
|
end
|
|
508
514
|
```
|
|
509
515
|
|
data/README_pt-BR.md
CHANGED
|
@@ -73,25 +73,27 @@ Cada recurso segue um conjunto consistente de padrões de métodos:
|
|
|
73
73
|
|
|
74
74
|
### Paginação
|
|
75
75
|
|
|
76
|
-
A
|
|
77
|
-
|
|
78
|
-
- **page**: Número da página atual (padrão: `1`)
|
|
79
|
-
- **size**: Quantidade de itens por página (padrão: `100`)
|
|
76
|
+
A gem utiliza por padrão `limit: 100, offset: 0` (nova paginação). O modelo legado `page`/`size` ainda funciona mas emite um aviso de depreciação.
|
|
80
77
|
|
|
81
78
|
#### Chamando com Paginação
|
|
82
79
|
|
|
83
80
|
```ruby
|
|
84
|
-
# Paginação padrão (
|
|
81
|
+
# Paginação padrão (limit: 100, offset: 0)
|
|
85
82
|
Conexa::Customer.all
|
|
86
83
|
|
|
87
|
-
#
|
|
88
|
-
Conexa::Customer.all(
|
|
84
|
+
# Com limite customizado
|
|
85
|
+
Conexa::Customer.all(limit: 50)
|
|
89
86
|
|
|
90
|
-
#
|
|
91
|
-
Conexa::Customer.all(
|
|
87
|
+
# Com offset
|
|
88
|
+
Conexa::Customer.all(limit: 50, offset: 100)
|
|
92
89
|
|
|
93
|
-
#
|
|
94
|
-
Conexa::Customer.
|
|
90
|
+
# Iteração automática com next_page
|
|
91
|
+
resultado = Conexa::Customer.all(limit: 50)
|
|
92
|
+
loop do
|
|
93
|
+
resultado.data.each { |cliente| processa(cliente) }
|
|
94
|
+
break unless resultado.has_next?
|
|
95
|
+
resultado = resultado.next_page
|
|
96
|
+
end
|
|
95
97
|
```
|
|
96
98
|
|
|
97
99
|
### Objeto Result
|
|
@@ -309,14 +311,22 @@ resultado = Conexa::Customer.all(limit: 50)
|
|
|
309
311
|
resultado.data # Array de clientes
|
|
310
312
|
resultado.pagination.limit # => 50
|
|
311
313
|
resultado.pagination.offset # => 0
|
|
312
|
-
resultado.
|
|
314
|
+
resultado.has_next? # => true/false
|
|
315
|
+
|
|
316
|
+
# Iterar por todas as páginas usando next_page
|
|
317
|
+
resultado = Conexa::Customer.all(limit: 50)
|
|
318
|
+
loop do
|
|
319
|
+
resultado.data.each { |cliente| processa(cliente) }
|
|
320
|
+
break unless resultado.has_next?
|
|
321
|
+
resultado = resultado.next_page
|
|
322
|
+
end
|
|
313
323
|
|
|
314
|
-
#
|
|
324
|
+
# Ou manualmente com offset
|
|
315
325
|
offset = 0
|
|
316
326
|
loop do
|
|
317
327
|
resultado = Conexa::Customer.all(limit: 50, offset: offset)
|
|
318
328
|
resultado.data.each { |cliente| processa(cliente) }
|
|
319
|
-
break unless resultado.
|
|
329
|
+
break unless resultado.has_next?
|
|
320
330
|
offset += 50
|
|
321
331
|
end
|
|
322
332
|
```
|
|
@@ -364,13 +374,12 @@ loop do
|
|
|
364
374
|
pagina += 1
|
|
365
375
|
end
|
|
366
376
|
|
|
367
|
-
# DEPOIS (novo)
|
|
368
|
-
|
|
377
|
+
# DEPOIS (novo — usando next_page)
|
|
378
|
+
resultado = Conexa::Customer.all(limit: 100)
|
|
369
379
|
loop do
|
|
370
|
-
resultado = Conexa::Customer.all(limit: 100, offset: offset)
|
|
371
380
|
resultado.data.each { |c| processa(c) }
|
|
372
|
-
break unless resultado.
|
|
373
|
-
|
|
381
|
+
break unless resultado.has_next?
|
|
382
|
+
resultado = resultado.next_page
|
|
374
383
|
end
|
|
375
384
|
```
|
|
376
385
|
|
data/REFERENCE.md
CHANGED
|
@@ -32,7 +32,7 @@ Conexa is a Brazilian SaaS platform for **recurring billing**, **subscription ma
|
|
|
32
32
|
|
|
33
33
|
```ruby
|
|
34
34
|
# Gemfile
|
|
35
|
-
gem 'conexa', '~> 0.0
|
|
35
|
+
gem 'conexa', '~> 0.1.0'
|
|
36
36
|
|
|
37
37
|
# Or install directly
|
|
38
38
|
gem install conexa
|
|
@@ -1034,7 +1034,7 @@ person.destroy
|
|
|
1034
1034
|
|
|
1035
1035
|
#### New Pagination (recommended) — `limit`/`offset`/`hasNext`
|
|
1036
1036
|
|
|
1037
|
-
All `#all` and `#find_by` methods
|
|
1037
|
+
All `#all` and `#find_by` methods use `limit`/`offset` by default. When no pagination params are passed, the gem defaults to `limit: 100, offset: 0`.
|
|
1038
1038
|
|
|
1039
1039
|
```ruby
|
|
1040
1040
|
# Page 1, 50 items
|
|
@@ -1043,24 +1043,35 @@ result = Conexa::Customer.all(limit: 50)
|
|
|
1043
1043
|
result.data # => Array of customers
|
|
1044
1044
|
result.pagination.limit # => 50
|
|
1045
1045
|
result.pagination.offset # => 0
|
|
1046
|
-
result.
|
|
1046
|
+
result.has_next? # => true/false
|
|
1047
1047
|
result.empty? # => false
|
|
1048
1048
|
|
|
1049
|
-
# Iterate all pages
|
|
1049
|
+
# Iterate all pages using next_page
|
|
1050
|
+
result = Conexa::Customer.all(limit: 100)
|
|
1051
|
+
loop do
|
|
1052
|
+
result.each { |customer| process(customer) }
|
|
1053
|
+
break unless result.has_next?
|
|
1054
|
+
result = result.next_page
|
|
1055
|
+
end
|
|
1056
|
+
|
|
1057
|
+
# Or manually with offset
|
|
1050
1058
|
offset = 0
|
|
1051
1059
|
loop do
|
|
1052
1060
|
result = Conexa::Customer.all(limit: 100, offset: offset)
|
|
1053
1061
|
break if result.empty?
|
|
1054
|
-
|
|
1055
1062
|
result.each { |customer| process(customer) }
|
|
1056
|
-
break unless result.
|
|
1063
|
+
break unless result.has_next?
|
|
1057
1064
|
offset += 100
|
|
1058
1065
|
end
|
|
1059
1066
|
```
|
|
1060
1067
|
|
|
1068
|
+
**`next_page`** — Fetches the next page automatically, preserving all original filter params. Raises `StopIteration` when there are no more pages.
|
|
1069
|
+
|
|
1070
|
+
**`has_next?`** — Returns `true` if more pages are available.
|
|
1071
|
+
|
|
1061
1072
|
#### Legacy Pagination (deprecated — removed 2026-08-01)
|
|
1062
1073
|
|
|
1063
|
-
If `
|
|
1074
|
+
If `page:` or `size:` is explicitly passed, the gem uses the old pagination model
|
|
1064
1075
|
(emitting a deprecation warning):
|
|
1065
1076
|
|
|
1066
1077
|
```ruby
|
|
@@ -1115,13 +1126,12 @@ loop do
|
|
|
1115
1126
|
page += 1
|
|
1116
1127
|
end
|
|
1117
1128
|
|
|
1118
|
-
# AFTER
|
|
1119
|
-
|
|
1129
|
+
# AFTER (using next_page)
|
|
1130
|
+
result = Conexa::Customer.all(limit: 100)
|
|
1120
1131
|
loop do
|
|
1121
|
-
result = Conexa::Customer.all(limit: 100, offset: offset)
|
|
1122
1132
|
result.each { |c| process(c) }
|
|
1123
|
-
break unless result.
|
|
1124
|
-
|
|
1133
|
+
break unless result.has_next?
|
|
1134
|
+
result = result.next_page
|
|
1125
1135
|
end
|
|
1126
1136
|
```
|
|
1127
1137
|
|
data/lib/conexa/authenticator.rb
CHANGED
data/lib/conexa/configuration.rb
CHANGED
data/lib/conexa/core_ext.rb
CHANGED
|
@@ -1,9 +1,14 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# Only define blank?/present? if not already provided (e.g., by ActiveSupport)
|
|
4
|
+
unless Object.method_defined?(:blank?)
|
|
5
|
+
class Object
|
|
6
|
+
def blank?
|
|
7
|
+
respond_to?(:empty?) ? !!empty? : !self
|
|
8
|
+
end
|
|
5
9
|
|
|
6
|
-
|
|
7
|
-
|
|
10
|
+
def present?
|
|
11
|
+
!blank?
|
|
12
|
+
end
|
|
8
13
|
end
|
|
9
14
|
end
|
data/lib/conexa/errors.rb
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module Conexa
|
|
2
4
|
class ConexaError < StandardError
|
|
3
5
|
end
|
|
@@ -38,11 +40,11 @@ module Conexa
|
|
|
38
40
|
|
|
39
41
|
def initialize(response)
|
|
40
42
|
@response = response
|
|
41
|
-
@errors = response['message']&.map do |
|
|
42
|
-
params =
|
|
43
|
+
@errors = response['message']&.map do |msg|
|
|
44
|
+
params = msg.values_at('message', 'parameter_name', 'type', 'url')
|
|
43
45
|
ParamError.new(*params)
|
|
44
46
|
end
|
|
45
|
-
super @errors&.map(&:message)
|
|
47
|
+
super @errors&.map(&:message)&.join(', ')
|
|
46
48
|
end
|
|
47
49
|
|
|
48
50
|
def to_h
|
data/lib/conexa/model.rb
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module Conexa
|
|
2
4
|
# Base class for all API resources (Customer, Charge, Contract, etc.)
|
|
3
5
|
#
|
|
4
6
|
# == Attribute Access
|
|
5
|
-
#
|
|
7
|
+
#
|
|
6
8
|
# Attributes are automatically accessible via method_missing:
|
|
7
9
|
# customer.name # => "Empresa ABC"
|
|
8
10
|
# customer.company_id # => 3
|
|
@@ -31,29 +33,11 @@ module Conexa
|
|
|
31
33
|
# instead of "recurring_sale_id". Explicit declaration ensures correctness.
|
|
32
34
|
#
|
|
33
35
|
class Model < ConexaObject
|
|
34
|
-
class << self
|
|
35
|
-
# DSL for primary key attribute with :id alias
|
|
36
|
-
# @example
|
|
37
|
-
# primary_key_attribute :charge_id
|
|
38
|
-
# # Generates: charge_id method + chargeId alias + id alias
|
|
39
|
-
def primary_key_attribute(snake_name)
|
|
40
|
-
camel_name = Util.camelize_str(snake_name.to_s)
|
|
41
|
-
|
|
42
|
-
define_method(snake_name) do
|
|
43
|
-
@attributes[snake_name.to_s]
|
|
44
|
-
end
|
|
45
|
-
|
|
46
|
-
alias_method camel_name.to_sym, snake_name
|
|
47
|
-
alias_method :id, snake_name
|
|
48
|
-
end
|
|
49
|
-
end
|
|
50
|
-
|
|
51
36
|
def create
|
|
52
37
|
set_primary_key Conexa::Request.post(self.class.show_url, params: to_hash).call(class_name).attributes['id']
|
|
53
38
|
fetch
|
|
54
39
|
end
|
|
55
40
|
|
|
56
|
-
|
|
57
41
|
def save
|
|
58
42
|
update Conexa::Request.patch(self.class.show_url(primary_key), params: unsaved_attributes).call(class_name)
|
|
59
43
|
self
|
|
@@ -86,11 +70,26 @@ module Conexa
|
|
|
86
70
|
|
|
87
71
|
def destroy
|
|
88
72
|
raise RequestError.new('Invalid ID') unless id.present?
|
|
89
|
-
update Conexa::Request.delete(
|
|
73
|
+
update Conexa::Request.delete(self.class.show_url(primary_key)).call(class_name)
|
|
90
74
|
self
|
|
91
75
|
end
|
|
92
76
|
|
|
93
77
|
class << self
|
|
78
|
+
# DSL for primary key attribute with :id alias
|
|
79
|
+
# @example
|
|
80
|
+
# primary_key_attribute :charge_id
|
|
81
|
+
# # Generates: charge_id method + chargeId alias + id alias
|
|
82
|
+
def primary_key_attribute(snake_name)
|
|
83
|
+
camel_name = Util.camelize_str(snake_name.to_s)
|
|
84
|
+
|
|
85
|
+
define_method(snake_name) do
|
|
86
|
+
@attributes[snake_name.to_s]
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
alias_method camel_name.to_sym, snake_name
|
|
90
|
+
alias_method :id, snake_name
|
|
91
|
+
end
|
|
92
|
+
|
|
94
93
|
def create(*args)
|
|
95
94
|
self.new(*args).create
|
|
96
95
|
end
|
|
@@ -101,18 +100,19 @@ module Conexa
|
|
|
101
100
|
end
|
|
102
101
|
alias :find :find_by_id
|
|
103
102
|
|
|
104
|
-
|
|
105
103
|
def find_by(params = Hash.new, page = nil, size = nil)
|
|
106
104
|
params = extract_page_size_or_params(page, size, **params)
|
|
107
105
|
raise RequestError.new('Invalid page size') if (!params.key?(:limit)) && (params[:page] < 1 or params[:size] < 1)
|
|
108
106
|
|
|
109
|
-
Conexa::Request.get(url, params: params).call
|
|
107
|
+
Conexa::Request.get(url, params: params).call(
|
|
108
|
+
underscored_class_name,
|
|
109
|
+
query_context: { resource_class: self, params: params }
|
|
110
|
+
)
|
|
110
111
|
end
|
|
111
112
|
alias :find_by_hash :find_by
|
|
112
113
|
|
|
113
114
|
def all(*args, **params)
|
|
114
|
-
params
|
|
115
|
-
find_by params
|
|
115
|
+
find_by(params, *args)
|
|
116
116
|
end
|
|
117
117
|
alias :where :all
|
|
118
118
|
|
|
@@ -131,7 +131,8 @@ module Conexa
|
|
|
131
131
|
end
|
|
132
132
|
|
|
133
133
|
def class_name
|
|
134
|
-
self.name.split('::').last
|
|
134
|
+
name = self.name.split('::').last
|
|
135
|
+
name[0].downcase + name[1..]
|
|
135
136
|
end
|
|
136
137
|
|
|
137
138
|
def underscored_class_name
|
|
@@ -147,20 +148,35 @@ module Conexa
|
|
|
147
148
|
end
|
|
148
149
|
size_val = args[1]
|
|
149
150
|
|
|
151
|
+
# Explicit new pagination (limit/offset)
|
|
150
152
|
if params.key?(:limit)
|
|
153
|
+
unless params[:limit].is_a?(Integer) && params[:limit].positive?
|
|
154
|
+
raise RequestError, "limit must be a positive integer"
|
|
155
|
+
end
|
|
156
|
+
|
|
151
157
|
params[:offset] ||= size_val if size_val.is_a?(Integer)
|
|
152
158
|
params[:offset] ||= 0
|
|
153
|
-
|
|
159
|
+
|
|
160
|
+
unless params[:offset].is_a?(Integer) && params[:offset] >= 0
|
|
161
|
+
raise RequestError, "offset must be a non-negative integer"
|
|
162
|
+
end
|
|
163
|
+
|
|
164
|
+
params.delete(:page)
|
|
154
165
|
params.delete(:size)
|
|
155
166
|
return params
|
|
156
167
|
end
|
|
157
168
|
|
|
169
|
+
# Explicit legacy pagination (page/size) — deprecated
|
|
158
170
|
if params.key?(:page) || params.key?(:size) || page_val.is_a?(Integer)
|
|
159
171
|
warn "DEPRECATION WARNING: O modelo antigo de paginação (page/size) será removido em 01 de agosto de 2026. Utilize limit e offset."
|
|
172
|
+
params[:page] ||= page_val || 1
|
|
173
|
+
params[:size] ||= size_val || 100
|
|
174
|
+
return params
|
|
160
175
|
end
|
|
161
176
|
|
|
162
|
-
|
|
163
|
-
params[:
|
|
177
|
+
# Default: new pagination
|
|
178
|
+
params[:limit] = 100
|
|
179
|
+
params[:offset] = 0
|
|
164
180
|
params
|
|
165
181
|
end
|
|
166
182
|
end
|
data/lib/conexa/object.rb
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module Conexa
|
|
2
4
|
# Base class for all Conexa objects with dynamic attribute access
|
|
3
5
|
#
|
|
@@ -24,8 +26,6 @@ module Conexa
|
|
|
24
26
|
end
|
|
25
27
|
|
|
26
28
|
def initialize(response = {})
|
|
27
|
-
# raise MissingCredentialsError.new("Missing :client_key for extra options #{options}") if options && !options[:client_key]
|
|
28
|
-
|
|
29
29
|
@attributes = Hash.new
|
|
30
30
|
@unsaved_attributes = Set.new
|
|
31
31
|
|
|
@@ -57,21 +57,13 @@ module Conexa
|
|
|
57
57
|
end]
|
|
58
58
|
end
|
|
59
59
|
|
|
60
|
-
def
|
|
61
|
-
|
|
60
|
+
def respond_to_missing?(name, include_private = false)
|
|
61
|
+
name_str = Util.to_snake_case(name.to_s)
|
|
62
|
+
return true if name_str.end_with?('=')
|
|
62
63
|
|
|
63
|
-
@attributes.
|
|
64
|
+
@attributes.key?(name_str) || @attributes.key?(name_str.to_sym) || super
|
|
64
65
|
end
|
|
65
66
|
|
|
66
|
-
# def to_s
|
|
67
|
-
# attributes_str = ''
|
|
68
|
-
# (attributes.keys - ['id', 'object']).sort.each do |key|
|
|
69
|
-
# attributes_str += " \033[1;33m#{key}:\033[0m#{self[key].inspect}" unless self[key].nil?
|
|
70
|
-
# end
|
|
71
|
-
# "\033[1;31m#<#{self.class.name}:\033[0;32m#{id}#{attributes_str}\033[0m\033[0m\033[1;31m>\033[0;32m"
|
|
72
|
-
# end
|
|
73
|
-
# # alias :inspect :to_s
|
|
74
|
-
|
|
75
67
|
protected
|
|
76
68
|
def update(attributes)
|
|
77
69
|
removed_attributes = @attributes.keys - attributes.to_hash.keys
|
|
@@ -127,7 +119,6 @@ module Conexa
|
|
|
127
119
|
super name, *args, &block
|
|
128
120
|
end
|
|
129
121
|
|
|
130
|
-
|
|
131
122
|
class << self
|
|
132
123
|
def convert(response, resource_name = nil, client_key=nil)
|
|
133
124
|
case response
|
|
@@ -154,7 +145,6 @@ module Conexa
|
|
|
154
145
|
|
|
155
146
|
def capitalize_name(name)
|
|
156
147
|
name.split('_').collect(&:capitalize).join
|
|
157
|
-
# name.gsub(/(\A\w|\_\w)/){ |str| str.gsub('_', '').upcase }
|
|
158
148
|
end
|
|
159
149
|
end
|
|
160
150
|
end
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
|
|
2
|
-
class OrderCommom < Model
|
|
1
|
+
# frozen_string_literal: true
|
|
3
2
|
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
#
|
|
3
|
+
module Conexa
|
|
4
|
+
class OrderCommon < Model
|
|
5
|
+
# Keep old name as alias for backwards compatibility
|
|
6
|
+
OrderCommom = self
|
|
7
7
|
|
|
8
8
|
#
|
|
9
9
|
# Request refund to Conexa api for this order
|
data/lib/conexa/request.rb
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
require 'uri'
|
|
2
4
|
require 'rest_client'
|
|
3
5
|
require 'multi_json'
|
|
4
6
|
|
|
5
|
-
|
|
6
|
-
|
|
7
7
|
module Conexa
|
|
8
8
|
class Request
|
|
9
9
|
DEFAULT_HEADERS = {
|
|
@@ -29,7 +29,6 @@ module Conexa
|
|
|
29
29
|
response = MultiJson.decode response.body
|
|
30
30
|
return {data: response.dig("data") || response, pagination: response.dig("pagination")}
|
|
31
31
|
|
|
32
|
-
|
|
33
32
|
rescue RestClient::Exception => error
|
|
34
33
|
begin
|
|
35
34
|
parsed_error = MultiJson.decode error.http_body
|
|
@@ -60,16 +59,18 @@ module Conexa
|
|
|
60
59
|
raise Conexa::ConnectionError.new $!
|
|
61
60
|
end
|
|
62
61
|
|
|
63
|
-
def call(
|
|
62
|
+
def call(resource_name, query_context: nil)
|
|
64
63
|
dt = run
|
|
65
64
|
|
|
66
65
|
if dt[:pagination]
|
|
67
|
-
|
|
68
|
-
data: ConexaObject.convert(dt[:data],
|
|
66
|
+
result = ConexaObject.convert({
|
|
67
|
+
data: ConexaObject.convert(dt[:data], resource_name),
|
|
69
68
|
pagination: ConexaObject.convert(dt[:pagination], "pagination")}, "result")
|
|
69
|
+
result.instance_variable_set(:@query_context, query_context) if query_context
|
|
70
|
+
return result
|
|
70
71
|
end
|
|
71
72
|
|
|
72
|
-
ConexaObject.convert(dt[:data],
|
|
73
|
+
ConexaObject.convert(dt[:data], resource_name)
|
|
73
74
|
end
|
|
74
75
|
|
|
75
76
|
def self.get(url, options={})
|
|
@@ -105,7 +106,7 @@ module Conexa
|
|
|
105
106
|
@parameters = Util.camelize_hash(@parameters)
|
|
106
107
|
aux.merge!({ payload: MultiJson.encode(@parameters)}) unless %w(GET DELETE).include? method
|
|
107
108
|
|
|
108
|
-
extra_headers = DEFAULT_HEADERS
|
|
109
|
+
extra_headers = DEFAULT_HEADERS.dup
|
|
109
110
|
extra_headers[:authorization] = "Bearer #{Conexa.configuration.api_token}" unless @auth
|
|
110
111
|
extra_headers[:params] = @parameters if method == "GET"
|
|
111
112
|
aux.merge!({ headers: extra_headers })
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module Conexa
|
|
2
4
|
class Result < ConexaObject
|
|
3
5
|
|
|
@@ -16,10 +18,31 @@ module Conexa
|
|
|
16
18
|
@attributes["pagination"]
|
|
17
19
|
end
|
|
18
20
|
|
|
19
|
-
def
|
|
20
|
-
|
|
21
|
+
def has_next?
|
|
22
|
+
pagination && pagination.has_next == true
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def next_page
|
|
26
|
+
raise StopIteration, "No more pages" unless has_next?
|
|
27
|
+
raise "No query context available for next_page" unless @query_context
|
|
28
|
+
|
|
29
|
+
resource_class = @query_context[:resource_class]
|
|
30
|
+
next_params = Marshal.load(Marshal.dump(@query_context[:params]))
|
|
31
|
+
|
|
32
|
+
next_params[:limit] = pagination.limit
|
|
33
|
+
next_params[:offset] = pagination.offset + pagination.limit
|
|
34
|
+
next_params.delete(:page)
|
|
35
|
+
next_params.delete(:size)
|
|
21
36
|
|
|
22
|
-
|
|
37
|
+
resource_class.find_by(next_params)
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def respond_to_missing?(name, include_private = false)
|
|
41
|
+
name_str = Util.to_snake_case(name.to_s)
|
|
42
|
+
return true if name_str.end_with?('=')
|
|
43
|
+
return true if @attributes["data"]&.respond_to?(name_str)
|
|
44
|
+
|
|
45
|
+
@attributes.key?(name_str) || @attributes.key?(name_str.to_sym) || super
|
|
23
46
|
end
|
|
24
47
|
|
|
25
48
|
def method_missing(name, *args, &block)
|
|
@@ -30,14 +53,18 @@ module Conexa
|
|
|
30
53
|
end
|
|
31
54
|
|
|
32
55
|
unless block_given?
|
|
33
|
-
|
|
34
56
|
if name.end_with?('=') && args.size == 1
|
|
35
57
|
attribute_name = name[0...-1]
|
|
36
58
|
return self[attribute_name] = args[0]
|
|
37
59
|
end
|
|
38
60
|
|
|
39
61
|
if args.size == 0
|
|
40
|
-
|
|
62
|
+
if @attributes.key?(name)
|
|
63
|
+
return @attributes[name]
|
|
64
|
+
elsif @attributes.key?(name.to_sym)
|
|
65
|
+
return @attributes[name.to_sym]
|
|
66
|
+
end
|
|
67
|
+
return nil
|
|
41
68
|
end
|
|
42
69
|
end
|
|
43
70
|
|
data/lib/conexa/token_manager.rb
CHANGED
data/lib/conexa/util.rb
CHANGED
|
@@ -1,44 +1,46 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module Conexa
|
|
2
4
|
class Util
|
|
3
5
|
class << self
|
|
4
6
|
|
|
5
|
-
SINGULARS =
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
7
|
+
SINGULARS = [
|
|
8
|
+
[/(ss)$/i, '\1'],
|
|
9
|
+
[/(n)ews$/i, '\1ews'],
|
|
10
|
+
[/([ti])a$/i, '\1um'],
|
|
11
|
+
[/((a)naly|(b)a|(d)iagno|(p)arenthe|(p)rogno|(s)ynop|(t)he)(sis|ses)$/i, '\1sis'],
|
|
12
|
+
[/(^analy)(sis|ses)$/i, '\1sis'],
|
|
13
|
+
[/([^f])ves$/i, '\1fe'],
|
|
14
|
+
[/(hive)s$/i, '\1'],
|
|
15
|
+
[/(tive)s$/i, '\1'],
|
|
16
|
+
[/([lr])ves$/i, '\1f'],
|
|
17
|
+
[/([^aeiouy]|qu)ies$/i, '\1y'],
|
|
18
|
+
[/(s)eries$/i, '\1eries'],
|
|
19
|
+
[/(m)ovies$/i, '\1ovie'],
|
|
20
|
+
[/(x|ch|ss|sh)es$/i, '\1'],
|
|
21
|
+
[/^(m|l)ice$/i, '\1ouse'],
|
|
22
|
+
[/(bus)(es)?$/i, '\1'],
|
|
23
|
+
[/(o)es$/i, '\1'],
|
|
24
|
+
[/(shoe)s$/i, '\1'],
|
|
25
|
+
[/(cris|test)(is|es)$/i, '\1is'],
|
|
26
|
+
[/^(a)x[ie]s$/i, '\1xis'],
|
|
27
|
+
[/(octop|vir)(us|i)$/i, '\1us'],
|
|
28
|
+
[/(alias|status)(es)?$/i, '\1'],
|
|
29
|
+
[/^(ox)en/i, '\1'],
|
|
30
|
+
[/(vert|ind)ices$/i, '\1ex'],
|
|
31
|
+
[/(matr)ices$/i, '\1ix'],
|
|
32
|
+
[/(quiz)zes$/i, '\1'],
|
|
33
|
+
[/(database)s$/i, '\1'],
|
|
34
|
+
[/s$/i, '']
|
|
35
|
+
].freeze
|
|
33
36
|
|
|
34
|
-
def singularize
|
|
35
|
-
|
|
36
|
-
SINGULARS.
|
|
37
|
-
|
|
38
|
-
|
|
37
|
+
def singularize(resource)
|
|
38
|
+
str = resource.to_s
|
|
39
|
+
SINGULARS.each do |pattern, replacement|
|
|
40
|
+
result = str.sub(pattern, replacement)
|
|
41
|
+
return resource.is_a?(Symbol) ? result.to_sym : result if result != str
|
|
39
42
|
end
|
|
40
|
-
|
|
41
|
-
resource.is_a?(Symbol) ? out.to_sym : out
|
|
43
|
+
resource
|
|
42
44
|
end
|
|
43
45
|
|
|
44
46
|
def to_sym string
|
|
@@ -77,18 +79,3 @@ module Conexa
|
|
|
77
79
|
end
|
|
78
80
|
end
|
|
79
81
|
end
|
|
80
|
-
|
|
81
|
-
class Hash
|
|
82
|
-
def except_nested(key)
|
|
83
|
-
r = Marshal.load(Marshal.dump(self))
|
|
84
|
-
r.except_nested!(key)
|
|
85
|
-
end
|
|
86
|
-
|
|
87
|
-
def except_nested!(key)
|
|
88
|
-
self.reject!{|k, _| k == key || k.to_s == key }
|
|
89
|
-
self.each do |_, v|
|
|
90
|
-
v.except_nested!(key) if v.is_a?(Hash)
|
|
91
|
-
v.map!{|obj| obj.except_nested!(key) if obj.is_a?(Hash)} if v.is_a?(Array)
|
|
92
|
-
end
|
|
93
|
-
end
|
|
94
|
-
end
|
data/lib/conexa/version.rb
CHANGED
data/lib/conexa.rb
CHANGED
|
@@ -9,7 +9,7 @@ require_relative "conexa/core_ext"
|
|
|
9
9
|
require_relative "conexa/errors"
|
|
10
10
|
require_relative "conexa/util"
|
|
11
11
|
require_relative "conexa/configuration"
|
|
12
|
-
require_relative "conexa/
|
|
12
|
+
require_relative "conexa/order_common"
|
|
13
13
|
require_relative "conexa/token_manager"
|
|
14
14
|
|
|
15
15
|
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: conexa
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.0
|
|
4
|
+
version: 0.1.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Guilherme Gazzinelli
|
|
@@ -153,7 +153,7 @@ files:
|
|
|
153
153
|
- lib/conexa/generators/install_generator.rb
|
|
154
154
|
- lib/conexa/model.rb
|
|
155
155
|
- lib/conexa/object.rb
|
|
156
|
-
- lib/conexa/
|
|
156
|
+
- lib/conexa/order_common.rb
|
|
157
157
|
- lib/conexa/request.rb
|
|
158
158
|
- lib/conexa/resources/account.rb
|
|
159
159
|
- lib/conexa/resources/address.rb
|