nylas 4.4.0 → 4.6.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 409a66c7c0f6450844eb2f3710d805b646f7f0993de0e4f78bd8506db667584e
4
- data.tar.gz: 37a1f95b1e9b5f6cb3de6e2df02a4c0c970c18e0b2c9456fc49329a8814a4a7f
3
+ metadata.gz: 34f645631bf41230a0c8709c0212c5b83fb24fa44bdf3b7b62429ec72ce92b41
4
+ data.tar.gz: 2d043ada950f30d03b65f45cb1e0635868cd7c092d919f992b1d9359519c995b
5
5
  SHA512:
6
- metadata.gz: 4bea6e6a62207fd428947b24ee0fb6a84ca86b7c29a56dd9a98223bbcd78534307875ee129b115719f888007027db9b270e59edf8f6a2ba2c09018fb084b7ba9
7
- data.tar.gz: ff7615d467aac326883ca08b7de8eaf3b794905162bb53a5f7c664bf40813b68c7781505237b404f4fc81220abc2962bebc59d4d2326dbc244f622719f685a87
6
+ metadata.gz: 3af07161869273f8fa33a38c97c286ec4c62aebb37b303e2fee348773c7d1c33ddb7c45531a95d792af21c90eca9055e1181b3fca2f5a412fd1809037ec5c70b
7
+ data.tar.gz: ea27a61dee30fc747b42fd2713e4755ca7f50243bbcf47d2bb8582aec96f1613ae3795206c62a5905ee4fbdc353c69f1c3f191e40f5b5b319728ccdd4cb80085
@@ -35,6 +35,7 @@ require_relative "nylas/rsvp"
35
35
  require_relative "nylas/timespan"
36
36
  require_relative "nylas/web_page"
37
37
  require_relative "nylas/nylas_date"
38
+ require_relative "nylas/when"
38
39
 
39
40
  # Custom collection types
40
41
  require_relative "nylas/search_collection"
@@ -60,6 +61,7 @@ require_relative "nylas/native_authentication"
60
61
  require_relative "nylas/http_client"
61
62
  require_relative "nylas/api"
62
63
 
64
+ require_relative "nylas/filter_attributes"
63
65
  # an SDK for interacting with the Nylas API
64
66
  # @see https://docs.nylas.com/reference
65
67
  module Nylas
@@ -86,4 +88,5 @@ module Nylas
86
88
  Types.registry[:web_page] = Types::ModelType.new(model: WebPage)
87
89
  Types.registry[:nylas_date] = NylasDateType.new
88
90
  Types.registry[:contact_group] = Types::ModelType.new(model: ContactGroup)
91
+ Types.registry[:when] = Types::ModelType.new(model: When)
89
92
  end
@@ -36,11 +36,28 @@ module Nylas
36
36
  )
37
37
  end
38
38
 
39
+ def exchange_code_for_token(code)
40
+ data = {
41
+ "client_id" => app_id,
42
+ "client_secret" => client.app_secret,
43
+ "grant_type" => "authorization_code",
44
+ "code" => code
45
+ }
46
+
47
+ response_json = execute(method: :post, path: "/oauth/token", payload: data)
48
+ response_json[:access_token]
49
+ end
50
+
39
51
  # @return [Collection<Contact>] A queryable collection of Contacts
40
52
  def contacts
41
53
  @contacts ||= Collection.new(model: Contact, api: self)
42
54
  end
43
55
 
56
+ # @return [Collection<ContactGroup>] A queryable collection of Contact Groups
57
+ def contact_groups
58
+ @contact_groups ||= Collection.new(model: ContactGroup, api: self)
59
+ end
60
+
44
61
  # @return [CurrentAccount] The account details for whomevers access token is set
45
62
  def current_account
46
63
  prevent_calling_if_missing_access_token(:current_account)
@@ -15,6 +15,9 @@ module Nylas
15
15
 
16
16
  attribute :name, :string
17
17
  attribute :description, :string
18
+ attribute :is_primary, :boolean
19
+ attribute :location, :string
20
+ attribute :timezone, :string
18
21
 
19
22
  attribute :read_only, :boolean
20
23
 
@@ -22,6 +25,10 @@ module Nylas
22
25
  read_only == true
23
26
  end
24
27
 
28
+ def primary?
29
+ is_primary
30
+ end
31
+
25
32
  def events
26
33
  api.events.where(calendar_id: id)
27
34
  end
@@ -29,7 +29,7 @@ module Nylas
29
29
  attribute :manager_name, :string
30
30
  attribute :office_location, :string
31
31
  attribute :notes, :string
32
- attribute :web_page, :web_page
32
+ attribute :source, :string
33
33
 
34
34
  has_n_of_attribute :groups, :contact_group
35
35
  has_n_of_attribute :emails, :email_address
@@ -4,7 +4,16 @@ module Nylas
4
4
  # Structure to represent the Contact Group schema
5
5
  # @see https://docs.nylas.com/reference#contactsid
6
6
  class ContactGroup
7
- include Model::Attributable
7
+ include Model
8
+ self.resources_path = "/contacts/groups"
9
+
10
+ self.creatable = false
11
+ self.destroyable = false
12
+ self.filterable = false
13
+ self.listable = true
14
+ self.showable = false
15
+ self.updatable = false
16
+
8
17
  attribute :id, :string
9
18
  attribute :object, :string
10
19
  attribute :account_id, :string
@@ -33,6 +33,8 @@ module Nylas
33
33
  attribute :folder, :folder
34
34
  has_n_of_attribute :labels, :label
35
35
 
36
+ transfer :api, to: %i[events files folder labels]
37
+
36
38
  def send!
37
39
  save
38
40
  execute(method: :post, path: "/send", payload: JSON.dump(draft_id: id, version: version))
@@ -15,6 +15,7 @@ module Nylas
15
15
  attribute :calendar_id, :string
16
16
  attribute :master_event_id, :string
17
17
  attribute :message_id, :string
18
+ attribute :ical_uid, :string
18
19
 
19
20
  attribute :busy, :boolean
20
21
  attribute :description, :string
@@ -25,7 +26,7 @@ module Nylas
25
26
  attribute :read_only, :boolean
26
27
  attribute :status, :string
27
28
  attribute :title, :string
28
- attribute :when, :timespan
29
+ attribute :when, :when
29
30
  attribute :original_start_time, :unix_timestamp
30
31
 
31
32
  def busy?
@@ -56,7 +56,7 @@ module Nylas
56
56
  def retrieve_file
57
57
  response = api.get(path: "#{resource_path}/download")
58
58
  filename = response.headers.fetch(:content_disposition, "").gsub("attachment; filename=", "")
59
- temp_file = Tempfile.new(filename)
59
+ temp_file = Tempfile.new(filename, encoding: "ascii-8bit")
60
60
  temp_file.write(response.body)
61
61
  temp_file.seek(0)
62
62
  temp_file
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Nylas
4
+ # Methods to check and raise error if extra attributes are present
5
+ class FilterAttributes
6
+ def initialize(attributes:, allowed_attributes:)
7
+ @attributes = attributes
8
+ @allowed_attributes = allowed_attributes
9
+ end
10
+
11
+ def check
12
+ return if extra_attributes.empty?
13
+
14
+ raise ArgumentError, "Only #{allowed_attributes} are allowed to be sent"
15
+ end
16
+
17
+ private
18
+
19
+ attr_reader :attributes, :allowed_attributes
20
+
21
+ def extra_attributes
22
+ attributes - allowed_attributes
23
+ end
24
+ end
25
+ end
@@ -1,6 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Nylas
4
+ require "yajl"
5
+
4
6
  # Plain HTTP client that can be used to interact with the Nylas API sans any type casting.
5
7
  class HttpClient # rubocop:disable Metrics/ClassLength
6
8
  HTTP_CODE_TO_EXCEPTIONS = {
@@ -130,9 +132,10 @@ module Nylas
130
132
  end
131
133
 
132
134
  def parse_response(response)
133
- response.is_a?(Enumerable) ? response : JSON.parse(response, symbolize_names: true)
134
- rescue JSON::ParserError
135
- response
135
+ return response if response.is_a?(Enumerable)
136
+
137
+ json = StringIO.new(response)
138
+ Yajl::Parser.new(symbolize_names: true).parse(json)
136
139
  end
137
140
  inform_on :parse_response, level: :debug, also_log: { result: true }
138
141
 
@@ -8,6 +8,7 @@ module Nylas
8
8
  self.raw_mime_type = "message/rfc822"
9
9
  self.resources_path = "/messages"
10
10
  allows_operations(showable: true, listable: true, filterable: true, searchable: true, updatable: true)
11
+ UPDATABLE_ATTRIBUTES = %i[label_ids folder_id starred unread].freeze
11
12
 
12
13
  attribute :id, :string
13
14
  attribute :object, :string
@@ -34,7 +35,12 @@ module Nylas
34
35
  has_n_of_attribute :events, :event
35
36
  has_n_of_attribute :files, :file
36
37
  attribute :folder, :folder
37
- has_n_of_attribute :labels, :label
38
+ attribute :folder_id, :string
39
+
40
+ has_n_of_attribute :labels, :label, exclude_when: [:saving]
41
+ has_n_of_attribute :label_ids, :string
42
+
43
+ transfer :api, to: %i[events files folder labels]
38
44
 
39
45
  def starred?
40
46
  starred
@@ -44,11 +50,42 @@ module Nylas
44
50
  unread
45
51
  end
46
52
 
53
+ def update(payload)
54
+ FilterAttributes.new(
55
+ attributes: payload.keys,
56
+ allowed_attributes: UPDATABLE_ATTRIBUTES
57
+ ).check
58
+
59
+ super(payload)
60
+ end
61
+
62
+ def update_folder(folder_id)
63
+ update(folder_id: folder_id)
64
+ end
65
+
47
66
  def expanded
48
67
  return self unless headers.nil?
49
68
 
50
69
  assign(api.execute(method: :get, path: resource_path, query: { view: "expanded" }))
51
70
  self
52
71
  end
72
+
73
+ def save_call
74
+ handle_folder
75
+
76
+ execute(
77
+ method: :put,
78
+ payload: attributes.serialize(keys: allowed_keys_for_save),
79
+ path: resource_path
80
+ )
81
+ end
82
+
83
+ def handle_folder
84
+ return if folder.nil?
85
+
86
+ self.folder_id = folder.id if folder_id.nil? && !self.to_h.dig(:folder, :id).nil?
87
+
88
+ self.folder = nil
89
+ end
53
90
  end
54
91
  end
@@ -4,6 +4,7 @@ require_relative "model/attribute_definition"
4
4
  require_relative "model/list_attribute_definition"
5
5
  require_relative "model/attributable"
6
6
  require_relative "model/attributes"
7
+ require_relative "model/transferable"
7
8
  module Nylas
8
9
  # Include this to define a class to represent an object returned from the API
9
10
  module Model
@@ -15,6 +16,7 @@ module Nylas
15
16
 
16
17
  def self.included(model)
17
18
  model.include(Attributable)
19
+ model.include(Transferable)
18
20
  model.extend(ClassMethods)
19
21
  model.extend(Forwardable)
20
22
  model.def_delegators :model_class, :creatable?, :filterable?, :listable?, :searchable?, :showable?,
@@ -26,7 +28,7 @@ module Nylas
26
28
  result = if persisted?
27
29
  raise ModelNotUpdatableError, self unless updatable?
28
30
 
29
- execute(method: :put, payload: attributes.serialize, path: resource_path)
31
+ save_call
30
32
  else
31
33
  create
32
34
  end
@@ -81,6 +83,22 @@ module Nylas
81
83
  JSON.dump(to_h)
82
84
  end
83
85
 
86
+ private
87
+
88
+ def allowed_keys_for_save
89
+ attributes.attribute_definitions.to_h.reject do |_k, v|
90
+ v.exclude_when.include?(:saving)
91
+ end.keys
92
+ end
93
+
94
+ def save_call
95
+ execute(
96
+ method: :put,
97
+ payload: attributes.serialize(keys: allowed_keys_for_save),
98
+ path: resource_path
99
+ )
100
+ end
101
+
84
102
  # Allows you to narrow in exactly what kind of model you're working with
85
103
  module ClassMethods
86
104
  attr_accessor :raw_mime_type, :creatable, :showable, :filterable, :searchable, :listable, :updatable,
@@ -2,7 +2,7 @@
2
2
 
3
3
  module Nylas
4
4
  module Model
5
- # Allows defining of tyypecastable attributes on a model
5
+ # Allows defining of typecastable attributes on a model
6
6
  module Attributable
7
7
  def self.included(model)
8
8
  model.extend(ClassMethods)
@@ -12,16 +12,6 @@ module Nylas
12
12
  assign(**initial_data)
13
13
  end
14
14
 
15
- protected def assign(**data) # rubocop:disable Style/AccessModifierDeclarations
16
- data.each do |attribute_name, value|
17
- if respond_to?(:"#{attribute_name}=")
18
- send(:"#{attribute_name}=", value)
19
- else
20
- Logging.logger.warn("#{attribute_name} is not defined as an attribute on #{self.class.name}")
21
- end
22
- end
23
- end
24
-
25
15
  def attributes
26
16
  @attributes ||= Attributes.new(self.class.attribute_definitions)
27
17
  end
@@ -31,6 +21,16 @@ module Nylas
31
21
  attributes.to_h
32
22
  end
33
23
 
24
+ protected
25
+
26
+ def assign(**data)
27
+ data.each do |attribute_name, value|
28
+ if respond_to?(:"#{attribute_name}=")
29
+ send(:"#{attribute_name}=", value)
30
+ end
31
+ end
32
+ end
33
+
34
34
  # Methods to call when tweaking Attributable classes
35
35
  module ClassMethods
36
36
  # rubocop:disable Naming/PredicateName
@@ -17,6 +17,8 @@ module Nylas
17
17
 
18
18
  def []=(key, value)
19
19
  data[key] = cast(key, value)
20
+ rescue Nylas::Registry::MissingKeyError
21
+ # Don't crash when a new attribute is added
20
22
  end
21
23
 
22
24
  # Merges data into the registry while casting input types correctly
@@ -0,0 +1,52 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Nylas
4
+ module Model
5
+ # Allows definition of attributes, which should transfer to other dependent attributes
6
+ module Transferable
7
+ def self.included(model)
8
+ model.extend(ClassMethods)
9
+ model.init_attribute_recipients
10
+ end
11
+
12
+ def initialize(**initial_data)
13
+ assign(**initial_data)
14
+ transfer_attributes
15
+ end
16
+
17
+ private
18
+
19
+ def transfer_attributes
20
+ self.class.attribute_recipients.each_pair do |name, recipient_names|
21
+ value = send(:"#{name}")
22
+ next if value.nil?
23
+
24
+ recipient_names.each do |recipient_name|
25
+ recipient = send(:"#{recipient_name}")
26
+ transfer_to_recipient(name, value, recipient) unless recipient.nil?
27
+ end
28
+ end
29
+ end
30
+
31
+ def transfer_to_recipient(name, value, recipient)
32
+ if recipient.respond_to?(:each)
33
+ recipient.each { |item| item.send(:"#{name}=", value) }
34
+ else
35
+ recipient.send(:"#{name}=", value)
36
+ end
37
+ end
38
+
39
+ # Methods to call when tweaking Transferable classes
40
+ module ClassMethods
41
+ attr_accessor :attribute_recipients
42
+ def init_attribute_recipients
43
+ self.attribute_recipients ||= {}
44
+ end
45
+
46
+ def transfer(*attributes, **opts)
47
+ attributes.each { |name| self.attribute_recipients[name] = opts[:to] }
48
+ end
49
+ end
50
+ end
51
+ end
52
+ end
@@ -12,5 +12,6 @@ module Nylas
12
12
  attribute :state, :string
13
13
  attribute :city, :string
14
14
  attribute :country, :string
15
+ attribute :secondary_address, :string
15
16
  end
16
17
  end
@@ -33,6 +33,8 @@ module Nylas
33
33
 
34
34
  has_n_of_attribute :label_ids, :string
35
35
 
36
+ transfer :api, to: %i[labels folders]
37
+
36
38
  UPDATABLE_ATTRIBUTES = %i[label_ids folder_id starred unread].freeze
37
39
  def update(data)
38
40
  unupdatable_attributes = data.keys.reject { |name| UPDATABLE_ATTRIBUTES.include?(name) }
@@ -43,6 +45,10 @@ module Nylas
43
45
  super(data)
44
46
  end
45
47
 
48
+ def update_folder(folder_id)
49
+ update(folder_id: folder_id)
50
+ end
51
+
46
52
  def starred?
47
53
  starred
48
54
  end
@@ -86,6 +86,7 @@ module Nylas
86
86
  end
87
87
 
88
88
  def serialize(object)
89
+ return nil if object.nil?
89
90
  object.to_i
90
91
  end
91
92
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Nylas
4
- VERSION = "4.4.0"
4
+ VERSION = "4.6.3"
5
5
  end
@@ -0,0 +1,48 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Nylas
4
+ # Structure to represent all the Nylas time types.
5
+ # @see https://docs.nylas.com/reference#section-time
6
+ class When
7
+ extend Forwardable
8
+
9
+ include Model::Attributable
10
+
11
+ attribute :object, :string
12
+
13
+ # when object == 'date'
14
+ attribute :date, :date
15
+
16
+ # when object == 'datespan'
17
+ attribute :start_date, :date
18
+ attribute :end_date, :date
19
+
20
+ # when object == 'time'
21
+ attribute :time, :unix_timestamp
22
+
23
+ # when object == 'timespan'
24
+ attribute :start_time, :unix_timestamp
25
+ attribute :end_time, :unix_timestamp
26
+
27
+ def_delegators :range, :cover?
28
+
29
+ def as_timespan
30
+ return unless object == "timespan"
31
+
32
+ Timespan.new(object: object, start_time: start_time, end_time: end_time)
33
+ end
34
+
35
+ def range
36
+ case object
37
+ when "timespan"
38
+ Range.new(start_time, end_time)
39
+ when "datespan"
40
+ Range.new(start_date, end_date)
41
+ when "date"
42
+ Range.new(date, date)
43
+ when "time"
44
+ Range.new(time, time)
45
+ end
46
+ end
47
+ end
48
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: nylas
3
3
  version: !ruby/object:Gem::Version
4
- version: 4.4.0
4
+ version: 4.6.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Nylas, Inc.
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-04-05 00:00:00.000000000 Z
11
+ date: 2020-12-19 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -254,6 +254,26 @@ dependencies:
254
254
  - - "<"
255
255
  - !ruby/object:Gem::Version
256
256
  version: '3.0'
257
+ - !ruby/object:Gem::Dependency
258
+ name: yajl-ruby
259
+ requirement: !ruby/object:Gem::Requirement
260
+ requirements:
261
+ - - "~>"
262
+ - !ruby/object:Gem::Version
263
+ version: '1.2'
264
+ - - ">="
265
+ - !ruby/object:Gem::Version
266
+ version: 1.2.1
267
+ type: :runtime
268
+ prerelease: false
269
+ version_requirements: !ruby/object:Gem::Requirement
270
+ requirements:
271
+ - - "~>"
272
+ - !ruby/object:Gem::Version
273
+ version: '1.2'
274
+ - - ">="
275
+ - !ruby/object:Gem::Version
276
+ version: 1.2.1
257
277
  description: Gem for interacting with the Nylas API.
258
278
  email: support@nylas.com
259
279
  executables: []
@@ -278,6 +298,7 @@ files:
278
298
  - lib/nylas/event.rb
279
299
  - lib/nylas/event_collection.rb
280
300
  - lib/nylas/file.rb
301
+ - lib/nylas/filter_attributes.rb
281
302
  - lib/nylas/folder.rb
282
303
  - lib/nylas/http_client.rb
283
304
  - lib/nylas/im_address.rb
@@ -291,6 +312,7 @@ files:
291
312
  - lib/nylas/model/attribute_definition.rb
292
313
  - lib/nylas/model/attributes.rb
293
314
  - lib/nylas/model/list_attribute_definition.rb
315
+ - lib/nylas/model/transferable.rb
294
316
  - lib/nylas/native_authentication.rb
295
317
  - lib/nylas/new_message.rb
296
318
  - lib/nylas/nylas_date.rb
@@ -308,6 +330,7 @@ files:
308
330
  - lib/nylas/version.rb
309
331
  - lib/nylas/web_page.rb
310
332
  - lib/nylas/webhook.rb
333
+ - lib/nylas/when.rb
311
334
  homepage:
312
335
  licenses:
313
336
  - MIT
@@ -333,7 +356,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
333
356
  - !ruby/object:Gem::Version
334
357
  version: '0'
335
358
  requirements: []
336
- rubygems_version: 3.0.3
359
+ rubygems_version: 3.0.8
337
360
  signing_key:
338
361
  specification_version: 4
339
362
  summary: Gem for interacting with the Nylas API