vng 3.0.0 → 3.0.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 3ce0b4bfa1bc71ea60e74d3ded65c3a610a5a9bd02d867fab27d0e59c7272a24
4
- data.tar.gz: 85345a62558558d22899adcdf1f052d42ef19b61d160dc0d49a87604f1292695
3
+ metadata.gz: 15e3e4b9f188fa73d3cdea696d1fac21c02ce00f1f67ada372fd328e0b1f1fac
4
+ data.tar.gz: 5d12461918e68ef048dc8ac0b7111d8a1337000c1815d2273fbe15409b0fd732
5
5
  SHA512:
6
- metadata.gz: a1d3770ed3fe0ef347ec57deb447af38ac3b93885fee6f20e557a61c7ea788001dd1d01485b4c95b9232ca7ae3e74397aaf382b77a21fb05304a33c20c6dd34a
7
- data.tar.gz: 53d11a0458c95f71a557531821141ec120b58dafe266952a06149fac84e348c0cd1e0a80d86298dfb242a20bfeb69010f8fad53f9e026fc7cb6418c123bd7666
6
+ metadata.gz: 3610cb024f1fcfaddd1d26fcfa82052bd43431a1890d2bed429c9eb0c8e1a7622a4be507bd57cec0c14c0cb08c03eda72f0d45a4acf97884b13c8b57004ed7f6
7
+ data.tar.gz: a0c5144d0e2458ec4830814d0689cf24a8cc3ce00915ba2c6649795fc3a45e6c5325c2f8a52ab650af03b522d73a92e1aca2efe93ffb11ded2b80855216704df
data/CHANGELOG.md CHANGED
@@ -1,4 +1,8 @@
1
- ## [3.0.0] - 2024-12-26
1
+ ## [3.0.1] - 2025-01-10
2
+
3
+ - Make Contact.edited_since lazy
4
+
5
+ ## [3.0.0] - 2025-01-09
2
6
 
3
7
  - Add Contact.edited_since(timestamp)
4
8
 
data/lib/vng/contact.rb CHANGED
@@ -1,40 +1,65 @@
1
1
  require 'vng/resource'
2
2
 
3
+ require ENV['VNG_MOCK'] ? 'vng/mock_request' : 'vng/http_request'
4
+ require 'vng/relation'
5
+
3
6
  module Vng
4
7
  # Provides methods to interact with Vonigo contacts.
5
8
  class Contact < Resource
6
9
  PATH = '/api/v1/data/Contacts/'
7
10
 
8
- attr_reader :id, :first_name, :last_name, :email, :phone, :client_id, :edited_at
11
+ # @param [Hash<Symbol, String>] data the options to initialize a resource.
12
+ # @option data [String] :object_id The unique ID of a Vonigo resource.
13
+ # @option data [Array] :fields The fields of a Vonigo resource.
14
+ def initialize(data = {})
15
+ @data = data
16
+ end
9
17
 
10
- def initialize(id:, first_name:, last_name:, email:, phone:, client_id:, edited_at: nil)
11
- @id = id
12
- @first_name = first_name
13
- @last_name = last_name
14
- @email = email
15
- @phone = phone
16
- @client_id = client_id
17
- @edited_at = edited_at
18
+ # @return [String] the resource’s unique ID.
19
+ def id
20
+ @data['objectID']
18
21
  end
19
22
 
20
- def self.edited_since(timestamp)
21
- body = { isCompleteObject: 'true', dateStart: timestamp.to_i, dateMode: 2 }
23
+ def active?
24
+ @data['isActive'] != 'false'
25
+ end
26
+
27
+ def first_name
28
+ self.class.value_for_field @data, 127
29
+ end
30
+
31
+ def last_name
32
+ self.class.value_for_field @data, 128
33
+ end
34
+
35
+ def email
36
+ self.class.value_for_field @data, 97
37
+ end
22
38
 
23
- data = request path: PATH, body: body, returning: 'Contacts'
39
+ def phone
40
+ self.class.value_for_field @data, 96
41
+ end
24
42
 
25
- data.filter_map do |body|
26
- next unless body['isActive']
43
+ def client_id
44
+ self.class.value_for_relation @data, 'client'
45
+ end
27
46
 
28
- id = body['objectID']
29
- first_name = value_for_field body, 127
30
- last_name = value_for_field body, 128
31
- email = value_for_field body, 97
32
- phone = value_for_field body, 96
33
- client_id = value_for_relation body, 'client'
34
- edited_at = Time.at Integer(body['dateLastEdited']), in: 'UTC'
47
+ def edited_at
48
+ Time.at Integer(@data['dateLastEdited']), in: 'UTC'
49
+ end
35
50
 
36
- new id: id, first_name: first_name, last_name: last_name, email: email, phone: phone, client_id: client_id, edited_at: edited_at
37
- end
51
+ # @return [Vng::Relation] the resources matching the conditions.
52
+ def self.where(conditions = {})
53
+ @where ||= Relation.new
54
+ @where.where conditions
55
+ end
56
+
57
+ def self.edited_since(timestamp)
58
+ contacts = where isCompleteObject: 'true', dateStart: timestamp.to_i, dateMode: 2
59
+ # TODO: select should accept sub-hash, e.g.
60
+ # .select :date_last_edited, fields: [134, 1036], relations: ['client']
61
+ contacts = contacts.select 'dateLastEdited', 'Fields', 'Relations'
62
+ contacts.lazy.filter(&:active?)
38
63
  end
39
64
 
40
65
  def self.create(first_name:, last_name:, email:, phone:, client_id:)
@@ -50,14 +75,7 @@ module Vng
50
75
  }
51
76
 
52
77
  data = request path: PATH, body: body
53
-
54
- id = data['Contact']['objectID']
55
- first_name = value_for_field data, 127
56
- last_name = value_for_field data, 128
57
- email = value_for_field data, 97
58
- phone = value_for_field data, 96
59
-
60
- new id: id, first_name: first_name, last_name: last_name, email: email, phone: phone, client_id: client_id
78
+ new data['Contact']
61
79
  end
62
80
  end
63
81
  end
@@ -0,0 +1,89 @@
1
+ module Vng
2
+ # Provides methods to iterate through collections of Vonigo resources.
3
+ # @private
4
+ class Relation
5
+ include Enumerable
6
+
7
+ # @yield [Hash] the options to change which items to iterate through.
8
+ def initialize(options = {}, &item_block)
9
+ @options = {parts: ['objectID', 'isActive'], next_page: 1}
10
+ @options.merge! options
11
+ @item_block = item_block
12
+ end
13
+
14
+ # Specifies which items to fetch when hitting the data API.
15
+ # @param [Hash<Symbol, String>] conditions The conditions for the items.
16
+ # @return [Vng::Relation] itself.
17
+ def where(conditions = {})
18
+ if @options[:conditions] != conditions
19
+ @items = []
20
+ @options.merge! conditions: conditions
21
+ end
22
+ self
23
+ end
24
+
25
+ # Specifies which parts of the resource to fetch when hitting the data API.
26
+ # @param [Array<Symbol>] parts The parts to fetch.
27
+ # @return [Vng::Relation] itself.
28
+ def select(*parts)
29
+ if @options[:parts] != parts + ['objectID', 'isActive']
30
+ @items = nil
31
+ @options.merge! parts: (parts + ['objectID', 'isActive'])
32
+ end
33
+ self
34
+ end
35
+
36
+ def each
37
+ @last_index = 0
38
+ while next_item = find_next
39
+ yield next_item
40
+ end
41
+ end
42
+
43
+ private
44
+
45
+ def request(path:, body: {}, query: {}, include_security_token: true)
46
+ if query.none? && include_security_token
47
+ body = body.merge securityToken: Vng.configuration.security_token
48
+ end
49
+
50
+ response_for path:, body:, query:
51
+ end
52
+
53
+ def response_for(path:, body: {}, query: {})
54
+ instrument do |data|
55
+ Request.new(host: Vng.configuration.host, path: path, query: query, body: body).run
56
+ end
57
+ end
58
+
59
+ def find_next
60
+ @items ||= []
61
+ if @items[@last_index].nil? && more_pages?
62
+ body = @options[:conditions].merge pageSize: 500, pageNo: @options[:next_page], sortMode: 3, sortDirection: 0
63
+
64
+ response_body = request path: '/api/v1/data/Contacts/', body: body
65
+
66
+ more_items = response_body['Contacts'].map do |contact_data|
67
+ Vng::Contact.new contact_data.slice(*@options[:parts])
68
+ end
69
+ @options.merge! next_page: (more_items.size == 500 ? @options[:next_page] + 1 : 1)
70
+ @items.concat more_items
71
+ end
72
+ @items[(@last_index +=1) -1]
73
+ end
74
+
75
+ def more_pages?
76
+ @last_index.zero? || @options[:next_page] > 1
77
+ end
78
+
79
+ # Provides instrumentation to ActiveSupport listeners
80
+ def instrument(&block)
81
+ data = { class_name: 'Vng::Contact' }
82
+ if defined?(ActiveSupport::Notifications)
83
+ ActiveSupport::Notifications.instrument 'Vng.request', data, &block
84
+ else
85
+ block.call data
86
+ end
87
+ end
88
+ end
89
+ end
data/lib/vng/resource.rb CHANGED
@@ -29,7 +29,7 @@ module Vng
29
29
  end
30
30
 
31
31
  def self.response_for(path:, body: {}, query: {})
32
- instrument do |data|
32
+ instrument do
33
33
  Request.new(host: host, path: path, query: query, body: body).run
34
34
  end
35
35
  end
@@ -55,10 +55,10 @@ module Vng
55
55
  # Provides instrumentation to ActiveSupport listeners
56
56
  def self.instrument(&block)
57
57
  data = { class_name: name }
58
- if defined?(ActiveSupport::Notifications)
58
+ if defined? ActiveSupport::Notifications
59
59
  ActiveSupport::Notifications.instrument 'Vng.request', data, &block
60
60
  else
61
- block.call data
61
+ block.call
62
62
  end
63
63
  end
64
64
  end
data/lib/vng/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Vng
2
- VERSION = '3.0.0'
2
+ VERSION = '3.0.1'
3
3
  end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: vng
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.0.0
4
+ version: 3.0.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - claudiob
8
8
  bindir: exe
9
9
  cert_chain: []
10
- date: 2025-01-10 00:00:00.000000000 Z
10
+ date: 2025-01-11 00:00:00.000000000 Z
11
11
  dependencies:
12
12
  - !ruby/object:Gem::Dependency
13
13
  name: simplecov
@@ -83,6 +83,7 @@ files:
83
83
  - lib/vng/price_block.rb
84
84
  - lib/vng/price_item.rb
85
85
  - lib/vng/price_list.rb
86
+ - lib/vng/relation.rb
86
87
  - lib/vng/resource.rb
87
88
  - lib/vng/route.rb
88
89
  - lib/vng/security_token.rb