nylas 4.0.0.rc2 → 4.0.0.rc3

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.
Files changed (45) hide show
  1. checksums.yaml +5 -5
  2. data/lib/nylas.rb +48 -5
  3. data/lib/nylas/account.rb +31 -0
  4. data/lib/nylas/api.rb +86 -2
  5. data/lib/nylas/calendar.rb +27 -0
  6. data/lib/nylas/collection.rb +46 -19
  7. data/lib/nylas/constraints.rb +12 -4
  8. data/lib/nylas/contact.rb +10 -2
  9. data/lib/nylas/current_account.rb +1 -4
  10. data/lib/nylas/delta.rb +46 -0
  11. data/lib/nylas/deltas.rb +17 -0
  12. data/lib/nylas/deltas_collection.rb +36 -0
  13. data/lib/nylas/draft.rb +51 -0
  14. data/lib/nylas/email_address.rb +1 -5
  15. data/lib/nylas/errors.rb +13 -0
  16. data/lib/nylas/event.rb +42 -0
  17. data/lib/nylas/event_collection.rb +13 -0
  18. data/lib/nylas/file.rb +58 -0
  19. data/lib/nylas/folder.rb +22 -0
  20. data/lib/nylas/http_client.rb +38 -29
  21. data/lib/nylas/im_address.rb +0 -5
  22. data/lib/nylas/label.rb +22 -0
  23. data/lib/nylas/message.rb +45 -0
  24. data/lib/nylas/message_headers.rb +25 -0
  25. data/lib/nylas/message_tracking.rb +11 -0
  26. data/lib/nylas/model.rb +75 -24
  27. data/lib/nylas/model/attributable.rb +2 -2
  28. data/lib/nylas/model/attributes.rb +3 -1
  29. data/lib/nylas/native_authentication.rb +31 -0
  30. data/lib/nylas/new_message.rb +29 -0
  31. data/lib/nylas/nylas_date.rb +5 -2
  32. data/lib/nylas/participant.rb +10 -0
  33. data/lib/nylas/phone_number.rb +0 -5
  34. data/lib/nylas/physical_address.rb +0 -5
  35. data/lib/nylas/raw_message.rb +15 -0
  36. data/lib/nylas/recurrence.rb +9 -0
  37. data/lib/nylas/rsvp.rb +18 -0
  38. data/lib/nylas/search_collection.rb +8 -0
  39. data/lib/nylas/thread.rb +52 -0
  40. data/lib/nylas/timespan.rb +18 -0
  41. data/lib/nylas/types.rb +62 -9
  42. data/lib/nylas/version.rb +1 -1
  43. data/lib/nylas/web_page.rb +0 -5
  44. data/lib/nylas/webhook.rb +19 -0
  45. metadata +31 -7
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 5fd4eb7f8982e3da95740a92b4ff5d1307d22bc7
4
- data.tar.gz: 3806c9465a159c517fc71165570a0c787751f79f
2
+ SHA256:
3
+ metadata.gz: fac446793677a8c9ae9f69d5d70e1ef43cb5a452e600f590665afa2f6d82f0de
4
+ data.tar.gz: d42bf8cf84bf85be8e4a3b6bf896492da0e3e6795f6eb5afb538d6cdc55cad78
5
5
  SHA512:
6
- metadata.gz: a1841957b48b50212c6026428401306cadf9c83fddb109e5567c0cb5bb5aa187e2a6383c804b546ffe1082d7bca395e73a2f63f035d20ab42a516fd44e831474
7
- data.tar.gz: a21d29a3a95331f855b5f4a312183fea5da5dcf73de7546df452d4723b080838bdc26fe376eec1455b98b108e3d92c0e8a2ec6742e05efaa1e80d72f5ff89d61
6
+ metadata.gz: 7fe7bdd1b56c7fb1e37ce318c28ed419bf38124e052c8a5a5de61c609d1132cdeff7a728126d549e3e0da0388303585e63701fdc37f01cab6b0c773d7587729c
7
+ data.tar.gz: 33d014b9b2cbc74fc1d52a5b203017d9272952baa207ada25e89aef029051539f4d1f9066b72a055e319783b13dee6bb4a5f0130c69f9de1a675de0b1bc0e11a
data/lib/nylas.rb CHANGED
@@ -17,15 +17,42 @@ require_relative "nylas/model"
17
17
 
18
18
  # Attribute types supported by the API
19
19
  require_relative "nylas/email_address"
20
+ require_relative "nylas/event"
21
+ require_relative "nylas/event_collection"
22
+ require_relative "nylas/file"
23
+ require_relative "nylas/folder"
20
24
  require_relative "nylas/im_address"
25
+ require_relative "nylas/label"
26
+ require_relative "nylas/message_headers"
27
+ require_relative "nylas/message_tracking"
28
+ require_relative "nylas/participant"
21
29
  require_relative "nylas/physical_address"
22
30
  require_relative "nylas/phone_number"
31
+ require_relative "nylas/recurrence"
32
+ require_relative "nylas/rsvp"
33
+ require_relative "nylas/timespan"
23
34
  require_relative "nylas/web_page"
24
35
  require_relative "nylas/nylas_date"
25
36
 
37
+ # Custom collection types
38
+ require_relative "nylas/search_collection"
39
+ require_relative "nylas/deltas_collection"
40
+
26
41
  # Models supported by the API
42
+ require_relative "nylas/account"
43
+ require_relative "nylas/calendar"
27
44
  require_relative "nylas/contact"
28
45
  require_relative "nylas/current_account"
46
+ require_relative "nylas/deltas"
47
+ require_relative "nylas/delta"
48
+ require_relative "nylas/draft"
49
+ require_relative "nylas/message"
50
+ require_relative "nylas/new_message"
51
+ require_relative "nylas/raw_message"
52
+ require_relative "nylas/thread"
53
+ require_relative "nylas/webhook"
54
+
55
+ require_relative "nylas/native_authentication"
29
56
 
30
57
  require_relative "nylas/http_client"
31
58
  require_relative "nylas/api"
@@ -33,10 +60,26 @@ require_relative "nylas/api"
33
60
  # an SDK for interacting with the Nylas API
34
61
  # @see https://docs.nylas.com/reference
35
62
  module Nylas
36
- Types.registry[:email_address] = EmailAddressType.new
37
- Types.registry[:im_address] = IMAddressType.new
38
- Types.registry[:physical_address] = PhysicalAddressType.new
39
- Types.registry[:phone_number] = PhoneNumberType.new
40
- Types.registry[:web_page] = WebPageType.new
63
+ Types.registry[:account] = Types::ModelType.new(model: Account)
64
+ Types.registry[:calendar] = Types::ModelType.new(model: Calendar)
65
+ Types.registry[:contact] = Types::ModelType.new(model: Contact)
66
+ Types.registry[:delta] = DeltaType.new
67
+ Types.registry[:draft] = Types::ModelType.new(model: Draft)
68
+ Types.registry[:email_address] = Types::ModelType.new(model: EmailAddress)
69
+ Types.registry[:event] = Types::ModelType.new(model: Event)
70
+ Types.registry[:file] = Types::ModelType.new(model: File)
71
+ Types.registry[:folder] = Types::ModelType.new(model: Folder)
72
+ Types.registry[:im_address] = Types::ModelType.new(model: IMAddress)
73
+ Types.registry[:label] = Types::ModelType.new(model: Label)
74
+ Types.registry[:message] = Types::ModelType.new(model: Message)
75
+ Types.registry[:message_headers] = MessageHeadersType.new
76
+ Types.registry[:message_tracking] = Types::ModelType.new(model: MessageTracking)
77
+ Types.registry[:participant] = Types::ModelType.new(model: Participant)
78
+ Types.registry[:physical_address] = Types::ModelType.new(model: PhysicalAddress)
79
+ Types.registry[:phone_number] = Types::ModelType.new(model: PhoneNumber)
80
+ Types.registry[:recurrence] = Types::ModelType.new(model: Recurrence)
81
+ Types.registry[:thread] = Types::ModelType.new(model: Thread)
82
+ Types.registry[:timespan] = Types::ModelType.new(model: Timespan)
83
+ Types.registry[:web_page] = Types::ModelType.new(model: WebPage)
41
84
  Types.registry[:nylas_date] = NylasDateType.new
42
85
  end
@@ -0,0 +1,31 @@
1
+ module Nylas
2
+ # Representation of the accounts for Account management purposes.
3
+ # @see https://docs.nylas.com/reference#account-management
4
+ class Account
5
+ include Model
6
+ self.listable = true
7
+ self.showable = true
8
+
9
+ attribute :id, :string
10
+ attribute :account_id, :string
11
+ attribute :billing_state, :string
12
+ attribute :sync_state, :string
13
+
14
+ attribute :email, :string
15
+ attribute :trial, :boolean
16
+
17
+ def upgrade
18
+ response = execute(method: :post, path: "#{resource_path}/upgrade")
19
+ response[:success]
20
+ end
21
+
22
+ def downgrade
23
+ response = execute(method: :post, path: "#{resource_path}/downgrade")
24
+ response[:success]
25
+ end
26
+
27
+ def self.resources_path(api:)
28
+ "/a/#{api.app_id}/accounts"
29
+ end
30
+ end
31
+ end
data/lib/nylas/api.rb CHANGED
@@ -3,7 +3,7 @@ module Nylas
3
3
  class API
4
4
  attr_accessor :client
5
5
  extend Forwardable
6
- def_delegators :client, :execute, :get, :post, :put, :delete
6
+ def_delegators :client, :execute, :get, :post, :put, :delete, :app_id
7
7
 
8
8
  include Logging
9
9
 
@@ -24,6 +24,13 @@ module Nylas
24
24
  end
25
25
  # rubocop:enable Metrics/ParameterLists
26
26
 
27
+ # @return [String] A Nylas access token for that particular user.
28
+ def authenticate(name:, email_address:, provider:, settings:, reauth_account_id: nil)
29
+ NativeAuthentication.new(api: self).authenticate(name: name, email_address: email_address,
30
+ provider: provider, settings: settings,
31
+ reauth_account_id: reauth_account_id)
32
+ end
33
+
27
34
  # @return [Collection<Contact>] A queryable collection of Contacts
28
35
  def contacts
29
36
  @contacts ||= Collection.new(model: Contact, api: self)
@@ -32,7 +39,84 @@ module Nylas
32
39
  # @return [CurrentAccount] The account details for whomevers access token is set
33
40
  def current_account
34
41
  prevent_calling_if_missing_access_token(:current_account)
35
- CurrentAccount.from_hash(client.execute(method: :get, path: "/account"), api: self)
42
+ CurrentAccount.from_hash(execute(method: :get, path: "/account"), api: self)
43
+ end
44
+
45
+ # @return [Collection<Account>] A queryable collection of {Account}s
46
+ def accounts
47
+ @accounts ||= Collection.new(model: Account, api: as(client.app_secret))
48
+ end
49
+
50
+ # @return [Collection<Calendar>] A queryable collection of {Calendar}s
51
+ def calendars
52
+ @calendars ||= Collection.new(model: Calendar, api: self)
53
+ end
54
+
55
+ # @return [DeltasCollection<Delta>] A queryable collection of Deltas, which are themselves a collection.
56
+ def deltas
57
+ @deltas ||= DeltasCollection.new(api: self)
58
+ end
59
+
60
+ # @return[Collection<Draft>] A queryable collection of {Draft} objects
61
+ def drafts
62
+ @drafts ||= Collection.new(model: Draft, api: self)
63
+ end
64
+
65
+ # @return [Collection<Event>] A queryable collection of {Event}s
66
+ def events
67
+ @events ||= EventCollection.new(model: Event, api: self)
68
+ end
69
+
70
+ # @return [Collection<Folder>] A queryable collection of {Folder}s
71
+ def folders
72
+ @folders ||= Collection.new(model: Folder, api: self)
73
+ end
74
+
75
+ # @return [Collection<File>] A queryable collection of {File}s
76
+ def files
77
+ @files ||= Collection.new(model: File, api: self)
78
+ end
79
+
80
+ # @return [Collection<Label>] A queryable collection of {Label} objects
81
+ def labels
82
+ @labels ||= Collection.new(model: Label, api: self)
83
+ end
84
+
85
+ # @return[Collection<Message>] A queryable collection of {Message} objects
86
+ def messages
87
+ @messages ||= Collection.new(model: Message, api: self)
88
+ end
89
+
90
+ # Revokes access to the Nylas API for the given access token
91
+ # @return [Boolean]
92
+ def revoke(access_token)
93
+ response = client.as(access_token).post(path: "/oauth/revoke")
94
+ response.code == 200 && response.empty?
95
+ end
96
+
97
+ # @param message [Hash, String, #send!]
98
+ # @return [Message] The resulting message
99
+ def send!(message)
100
+ return message.send! if message.respond_to?(:send!)
101
+ return NewMessage.new(**message.merge(api: self)).send! if message.respond_to?(:key?)
102
+ return RawMessage.new(message, api: self).send! if message.is_a? String
103
+ end
104
+
105
+ # Allows you to get an API that acts as a different user but otherwise has the same settings
106
+ # @param [String] Oauth Access token or app secret used to authenticate with the API
107
+ # @return [API]
108
+ def as(access_token)
109
+ API.new(client: client.as(access_token))
110
+ end
111
+
112
+ # @return [Collection<Thread>] A queryable collection of Threads
113
+ def threads
114
+ @threads ||= Collection.new(model: Thread, api: self)
115
+ end
116
+
117
+ # @return [Collection<Webhook>] A queryable collection of {Webhook}s
118
+ def webhooks
119
+ @webhooks ||= Collection.new(model: Webhook, api: as(client.app_secret))
36
120
  end
37
121
 
38
122
  private def prevent_calling_if_missing_access_token(method_name)
@@ -0,0 +1,27 @@
1
+ module Nylas
2
+ # Ruby bindings for the Nylas Calendar API
3
+ # @see https://docs.nylas.com/reference#calendars
4
+ class Calendar
5
+ include Model
6
+ self.resources_path = "/calendars"
7
+ allows_operations(listable: true, filterable: true, showable: true)
8
+
9
+ attribute :id, :string
10
+ attribute :account_id, :string
11
+
12
+ attribute :object, :string
13
+
14
+ attribute :name, :string
15
+ attribute :description, :string
16
+
17
+ attribute :read_only, :boolean
18
+
19
+ def read_only?
20
+ read_only == true
21
+ end
22
+
23
+ def events
24
+ api.events.where(calendar_id: id)
25
+ end
26
+ end
27
+ end
@@ -2,56 +2,70 @@ module Nylas
2
2
  # An enumerable for working with index and search endpoints
3
3
  class Collection
4
4
  attr_accessor :model, :api, :constraints
5
+ extend Forwardable
6
+ def_delegators :each, :map, :select, :reject, :to_a, :take
7
+ def_delegators :to_a, :first, :last, :[]
8
+
5
9
  def initialize(model:, api:, constraints: nil)
6
10
  self.constraints = Constraints.from_constraints(constraints)
7
11
  self.model = model
8
12
  self.api = api
9
13
  end
10
14
 
15
+ # Instantiates a new model
11
16
  def new(**attributes)
12
- model.from_hash(attributes, api: api)
17
+ model.new(attributes.merge(api: api))
13
18
  end
14
19
 
15
20
  def create(**attributes)
16
- model.raise_if_read_only
17
- instance = model.from_hash(attributes, api: api)
21
+ instance = model.new(attributes.merge(api: api))
18
22
  instance.save
19
23
  instance
20
24
  end
21
25
 
26
+ # Merges in additional filters when querying the collection
27
+ # @return [Collection<Model>]
22
28
  def where(filters)
23
- raise NotImplementedError, "#{model} does not support search" unless model.searchable?
29
+ raise ModelNotFilterableError, model unless model.filterable?
24
30
  self.class.new(model: model, api: api, constraints: constraints.merge(where: filters))
25
31
  end
26
32
 
33
+ def search(query)
34
+ raise ModelNotSearchableError, model unless model.searchable?
35
+ SearchCollection.new(model: model, api: api, constraints: constraints.merge(where: { q: query }))
36
+ end
37
+
38
+ # The collection now returns a string representation of the model in a particular mime type instead of
39
+ # Model objects
40
+ # @return [Collection<String>]
41
+ def raw
42
+ raise ModelNotAvailableAsRawError, model unless model.exposable_as_raw?
43
+ self.class.new(model: model, api: api, constraints: constraints.merge(accept: model.raw_mime_type))
44
+ end
45
+
46
+ # @return [Integer]
27
47
  def count
28
48
  self.class.new(model: model, api: api, constraints: constraints.merge(view: "count")).execute[:count]
29
49
  end
30
50
 
31
- def first
32
- model.from_hash(execute.first, api: api)
51
+ # @return [Collection<Model>]
52
+ def expanded
53
+ self.class.new(model: model, api: api, constraints: constraints.merge(view: "expanded"))
33
54
  end
34
55
 
35
- def[](index)
36
- model.from_hash(execute(index), api: api)
56
+ # @return [Array<String>]
57
+ def ids
58
+ self.class.new(model: model, api: api, constraints: constraints.merge(view: "ids")).execute
37
59
  end
38
60
 
39
61
  # Iterates over a single page of results based upon current pagination settings
40
62
  def each
41
63
  return enum_for(:each) unless block_given?
42
64
  execute.each do |result|
43
- yield(model.from_hash(result, api: api))
65
+ yield(model.new(result.merge(api: api)))
44
66
  end
45
67
  end
46
68
 
47
- def to_a
48
- each.to_a
49
- end
50
-
51
- def map(&block)
52
- each.map(&block)
53
- end
54
-
55
69
  def limit(quantity)
56
70
  self.class.new(model: model, api: api, constraints: constraints.merge(limit: quantity))
57
71
  end
@@ -76,7 +90,7 @@ module Nylas
76
90
  end
77
91
  end
78
92
 
79
- def next_page(accumulated: nil, current_page: nil)
93
+ def next_page(accumulated:, current_page:)
80
94
  return nil unless more_pages?(accumulated, current_page)
81
95
  self.class.new(model: model, api: api, constraints: constraints.next_page)
82
96
  end
@@ -91,6 +105,18 @@ module Nylas
91
105
  # Retrieves a record. Nylas doesn't support where filters on GET so this will not take into
92
106
  # consideration other query constraints, such as where clauses.
93
107
  def find(id)
108
+ constraints.accept == "application/json" ? find_model(id) : find_raw(id)
109
+ end
110
+
111
+ def find_raw(id)
112
+ api.execute(to_be_executed.merge(path: "#{resources_path}/#{id}")).to_s
113
+ end
114
+
115
+ def resources_path
116
+ model.resources_path(api: api)
117
+ end
118
+
119
+ def find_model(id)
94
120
  instance = model.from_hash({ id: id }, api: api)
95
121
  instance.reload
96
122
  instance
@@ -98,7 +124,8 @@ module Nylas
98
124
 
99
125
  # @return [Hash] Specification for request to be passed to {API#execute}
100
126
  def to_be_executed
101
- { method: :get, path: model.resources_path, query: constraints.to_query }
127
+ { method: :get, path: resources_path, query: constraints.to_query,
128
+ headers: constraints.to_headers }
102
129
  end
103
130
 
104
131
  # Retrieves the data from the API for the particular constraints
@@ -1,22 +1,26 @@
1
1
  module Nylas
2
2
  # The constraints a particular GET request will include in their query params
3
3
  class Constraints
4
- attr_accessor :where, :limit, :offset, :view, :per_page
5
- def initialize(where: {}, limit: nil, offset: 0, view: nil, per_page: 100)
4
+ attr_accessor :where, :limit, :offset, :view, :per_page, :accept
5
+ # rubocop:disable Metrics/ParameterLists
6
+ def initialize(where: {}, limit: nil, offset: 0, view: nil, per_page: 100, accept: "application/json")
6
7
  self.where = where
7
8
  self.limit = limit
8
9
  self.offset = offset
9
10
  self.view = view
10
11
  self.per_page = per_page
12
+ self.accept = accept
11
13
  end
12
14
 
13
- def merge(where: {}, limit: nil, offset: nil, view: nil, per_page: nil)
15
+ def merge(where: {}, limit: nil, offset: nil, view: nil, per_page: nil, accept: nil)
14
16
  Constraints.new(where: where.merge(where),
15
17
  limit: limit || self.limit,
16
18
  per_page: per_page || self.per_page,
17
19
  offset: offset || self.offset,
18
- view: view || self.view)
20
+ view: view || self.view,
21
+ accept: accept || self.accept)
19
22
  end
23
+ # rubocop:enable Metrics/ParameterLists
20
24
 
21
25
  def next_page
22
26
  merge(offset: offset + per_page)
@@ -32,6 +36,10 @@ module Nylas
32
36
  query
33
37
  end
34
38
 
39
+ def to_headers
40
+ accept == "application/json" ? {} : { "Accept" => accept, "Content-types" => accept }
41
+ end
42
+
35
43
  def limit_for_query
36
44
  !limit.nil? && limit < per_page ? limit : per_page
37
45
  end
data/lib/nylas/contact.rb CHANGED
@@ -4,12 +4,20 @@ module Nylas
4
4
  class Contact
5
5
  include Model
6
6
  self.resources_path = "/contacts"
7
+ self.creatable = true
8
+ self.listable = true
9
+ self.showable = true
10
+ self.filterable = true
11
+ self.updatable = true
12
+ self.destroyable = true
7
13
 
8
- attribute :id, :string, exclude_when: %i(creating updating)
14
+ attribute :id, :string, exclude_when: %i[creating updating]
9
15
  attribute :object, :string, default: "contact"
10
- attribute :account_id, :string, exclude_when: %i(creating updating)
16
+ attribute :account_id, :string, exclude_when: %i[creating updating]
17
+
11
18
  attribute :given_name, :string
12
19
  attribute :middle_name, :string
20
+ attribute :picture_url, :string
13
21
  attribute :surname, :string
14
22
  attribute :birthday, :nylas_date
15
23
  attribute :suffix, :string