parse-stack 1.7.3 → 1.9.1

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 (85) hide show
  1. checksums.yaml +5 -5
  2. data/.github/workflows/ruby.yml +36 -0
  3. data/.solargraph.yml +23 -0
  4. data/.travis.yml +6 -3
  5. data/Changes.md +84 -22
  6. data/Gemfile +14 -12
  7. data/Gemfile.lock +110 -60
  8. data/README.md +67 -24
  9. data/Rakefile +14 -14
  10. data/bin/parse-console +1 -0
  11. data/lib/parse/api/aggregate.rb +59 -0
  12. data/lib/parse/api/all.rb +2 -1
  13. data/lib/parse/api/analytics.rb +0 -3
  14. data/lib/parse/api/batch.rb +3 -5
  15. data/lib/parse/api/cloud_functions.rb +0 -3
  16. data/lib/parse/api/config.rb +0 -4
  17. data/lib/parse/api/files.rb +3 -7
  18. data/lib/parse/api/hooks.rb +4 -8
  19. data/lib/parse/api/objects.rb +9 -14
  20. data/lib/parse/api/push.rb +0 -4
  21. data/lib/parse/api/schema.rb +2 -6
  22. data/lib/parse/api/server.rb +4 -7
  23. data/lib/parse/api/sessions.rb +2 -5
  24. data/lib/parse/api/users.rb +9 -14
  25. data/lib/parse/client.rb +55 -50
  26. data/lib/parse/client/authentication.rb +29 -33
  27. data/lib/parse/client/batch.rb +8 -11
  28. data/lib/parse/client/body_builder.rb +19 -20
  29. data/lib/parse/client/caching.rb +23 -28
  30. data/lib/parse/client/protocol.rb +11 -12
  31. data/lib/parse/client/request.rb +4 -6
  32. data/lib/parse/client/response.rb +5 -7
  33. data/lib/parse/model/acl.rb +14 -12
  34. data/lib/parse/model/associations/belongs_to.rb +19 -24
  35. data/lib/parse/model/associations/collection_proxy.rb +328 -317
  36. data/lib/parse/model/associations/has_many.rb +22 -27
  37. data/lib/parse/model/associations/has_one.rb +7 -12
  38. data/lib/parse/model/associations/pointer_collection_proxy.rb +5 -13
  39. data/lib/parse/model/associations/relation_collection_proxy.rb +5 -9
  40. data/lib/parse/model/bytes.rb +8 -10
  41. data/lib/parse/model/classes/installation.rb +2 -4
  42. data/lib/parse/model/classes/product.rb +2 -5
  43. data/lib/parse/model/classes/role.rb +3 -5
  44. data/lib/parse/model/classes/session.rb +2 -5
  45. data/lib/parse/model/classes/user.rb +21 -17
  46. data/lib/parse/model/core/actions.rb +31 -46
  47. data/lib/parse/model/core/builder.rb +6 -6
  48. data/lib/parse/model/core/errors.rb +0 -1
  49. data/lib/parse/model/core/fetching.rb +45 -50
  50. data/lib/parse/model/core/properties.rb +53 -68
  51. data/lib/parse/model/core/querying.rb +292 -282
  52. data/lib/parse/model/core/schema.rb +89 -92
  53. data/lib/parse/model/date.rb +16 -23
  54. data/lib/parse/model/file.rb +171 -174
  55. data/lib/parse/model/geopoint.rb +12 -16
  56. data/lib/parse/model/model.rb +31 -37
  57. data/lib/parse/model/object.rb +58 -70
  58. data/lib/parse/model/pointer.rb +177 -176
  59. data/lib/parse/model/push.rb +8 -10
  60. data/lib/parse/model/shortnames.rb +1 -2
  61. data/lib/parse/model/time_zone.rb +3 -5
  62. data/lib/parse/query.rb +70 -37
  63. data/lib/parse/query/constraint.rb +4 -6
  64. data/lib/parse/query/constraints.rb +62 -20
  65. data/lib/parse/query/operation.rb +8 -11
  66. data/lib/parse/query/ordering.rb +45 -49
  67. data/lib/parse/stack.rb +15 -11
  68. data/lib/parse/stack/generators/rails.rb +28 -30
  69. data/lib/parse/stack/generators/templates/model.erb +5 -6
  70. data/lib/parse/stack/generators/templates/model_installation.rb +0 -1
  71. data/lib/parse/stack/generators/templates/model_role.rb +0 -1
  72. data/lib/parse/stack/generators/templates/model_session.rb +0 -1
  73. data/lib/parse/stack/generators/templates/model_user.rb +0 -1
  74. data/lib/parse/stack/generators/templates/parse.rb +9 -9
  75. data/lib/parse/stack/generators/templates/webhooks.rb +1 -2
  76. data/lib/parse/stack/railtie.rb +2 -4
  77. data/lib/parse/stack/tasks.rb +70 -86
  78. data/lib/parse/stack/version.rb +1 -1
  79. data/lib/parse/webhooks.rb +19 -26
  80. data/lib/parse/webhooks/payload.rb +26 -28
  81. data/lib/parse/webhooks/registration.rb +23 -31
  82. data/parse-stack.gemspec +28 -28
  83. data/parse-stack.png +0 -0
  84. metadata +27 -25
  85. data/.github/parse-ruby-sdk.png +0 -0
@@ -1,199 +1,200 @@
1
1
  # encoding: UTF-8
2
2
  # frozen_string_literal: true
3
3
 
4
- require 'active_model'
5
- require 'active_support'
6
- require 'active_support/inflector'
7
- require 'active_support/core_ext'
8
- require 'active_model_serializers'
9
- require_relative 'model'
4
+ require "active_model"
5
+ require "active_support"
6
+ require "active_support/inflector"
7
+ require "active_support/core_ext"
8
+ require "active_model_serializers"
9
+ require_relative "model"
10
+
10
11
  module Parse
11
12
 
12
- # The Pointer class represents the pointer type in Parse and is the superclass
13
- # of Parse::Object types. A pointer can be considered a type of Parse::Object
14
- # in which only the class name and id is known. In most cases, you may not
15
- # deal with Parse::Pointer objects directly if you have defined all your
16
- # Parse::Object subclasses.
17
- #
18
- # A `Parse::Pointer` only contains data about the specific Parse class and
19
- # the `id` for the object. Therefore, creating an instance of any
20
- # Parse::Object subclass with only the `:id` field set will be
21
- # considered in "pointer" state even though its specific class is not
22
- # `Parse::Pointer` type. The only case that you may have a Parse::Pointer
23
- # is in the case where an object was received for one of your classes and
24
- # the framework has no registered class handler for it.
25
- # Assume you have the tables `Post`, `Comment` and `Author` defined in your
26
- # remote Parse database, but have only defined `Post` and `Commentary`
27
- # locally.
28
- # @example
29
- # class Post < Parse::Object
30
- # end
31
- #
32
- # class Commentary < Parse::Object
33
- # belongs_to :post
34
- # belongs_to :author
35
- # end
36
- #
37
- # comment = Commentary.first
38
- # comment.post? # true because it is non-nil
39
- # comment.artist? # true because it is non-nil
40
- #
41
- # # both are true because they are in a Pointer state
42
- # comment.post.pointer? # true
43
- # comment.author.pointer? # true
44
- #
45
- # # we have defined a Post class handler
46
- # comment.post # <Post @parse_class="Post", @id="xdqcCqfngz">
47
- #
48
- # # we have not defined an Author class handler
49
- # comment.author # <Parse::Pointer @parse_class="Author", @id="hZLbW6ofKC">
50
- #
51
- #
52
- # comment.post.fetch # fetch the relation
53
- # comment.post.pointer? # false, it is now a full object.
54
- #
55
- # The effect is that for any unknown classes that the framework encounters,
56
- # it will generate Parse::Pointer instances until you define those classes
57
- # with valid properties and associations. While this might be ok for some
58
- # classes you do not use, we still recommend defining all your Parse classes
59
- # locally in the framework.
60
- #
61
- # Once you have a subclass, you may also create a Parse::Pointer object using
62
- # the _pointer_ method.
63
- # @example
64
- # Parse::User.pointer("123456") # => Parse::Pointer for "_User" class
65
- #
66
- # @see Parse::Object
67
- class Pointer < Model
68
- # The default attributes in a Parse Pointer hash.
69
- ATTRIBUTES = { __type: :string, className: :string, objectId: :string}.freeze
70
- # @return [String] the name of the Parse class for this pointer.
71
- attr_accessor :parse_class
72
- # @return [String] the objectId field
73
- attr_accessor :id
74
-
75
- # @return [Model::TYPE_POINTER]
76
- def __type; Parse::Model::TYPE_POINTER; end;
77
- alias_method :className, :parse_class
78
- # A Parse object as a className field and objectId. In ruby, we will use the
79
- # id attribute method, but for usability, we will also alias it to objectId
80
- alias_method :objectId, :id
81
-
82
- # A Parse pointer only requires the name of the remote Parse collection name,
83
- # and the `objectId` of the record.
84
- # @param table [String] The Parse class name in the Parse database.
85
- # @param oid [String] The objectId
86
- def initialize(table, oid)
87
- @parse_class = table.to_s
88
- @id = oid.to_s
89
- end
13
+ # The Pointer class represents the pointer type in Parse and is the superclass
14
+ # of Parse::Object types. A pointer can be considered a type of Parse::Object
15
+ # in which only the class name and id is known. In most cases, you may not
16
+ # deal with Parse::Pointer objects directly if you have defined all your
17
+ # Parse::Object subclasses.
18
+ #
19
+ # A `Parse::Pointer` only contains data about the specific Parse class and
20
+ # the `id` for the object. Therefore, creating an instance of any
21
+ # Parse::Object subclass with only the `:id` field set will be
22
+ # considered in "pointer" state even though its specific class is not
23
+ # `Parse::Pointer` type. The only case that you may have a Parse::Pointer
24
+ # is in the case where an object was received for one of your classes and
25
+ # the framework has no registered class handler for it.
26
+ # Assume you have the tables `Post`, `Comment` and `Author` defined in your
27
+ # remote Parse database, but have only defined `Post` and `Commentary`
28
+ # locally.
29
+ # @example
30
+ # class Post < Parse::Object
31
+ # end
32
+ #
33
+ # class Commentary < Parse::Object
34
+ # belongs_to :post
35
+ # belongs_to :author
36
+ # end
37
+ #
38
+ # comment = Commentary.first
39
+ # comment.post? # true because it is non-nil
40
+ # comment.artist? # true because it is non-nil
41
+ #
42
+ # # both are true because they are in a Pointer state
43
+ # comment.post.pointer? # true
44
+ # comment.author.pointer? # true
45
+ #
46
+ # # we have defined a Post class handler
47
+ # comment.post # <Post @parse_class="Post", @id="xdqcCqfngz">
48
+ #
49
+ # # we have not defined an Author class handler
50
+ # comment.author # <Parse::Pointer @parse_class="Author", @id="hZLbW6ofKC">
51
+ #
52
+ #
53
+ # comment.post.fetch # fetch the relation
54
+ # comment.post.pointer? # false, it is now a full object.
55
+ #
56
+ # The effect is that for any unknown classes that the framework encounters,
57
+ # it will generate Parse::Pointer instances until you define those classes
58
+ # with valid properties and associations. While this might be ok for some
59
+ # classes you do not use, we still recommend defining all your Parse classes
60
+ # locally in the framework.
61
+ #
62
+ # Once you have a subclass, you may also create a Parse::Pointer object using
63
+ # the _pointer_ method.
64
+ # @example
65
+ # Parse::User.pointer("123456") # => Parse::Pointer for "_User" class
66
+ #
67
+ # @see Parse::Object
68
+ class Pointer < Model
69
+ # The default attributes in a Parse Pointer hash.
70
+ ATTRIBUTES = { __type: :string, className: :string, objectId: :string }.freeze
71
+ # @return [String] the name of the Parse class for this pointer.
72
+ attr_accessor :parse_class
73
+ # @return [String] the objectId field
74
+ attr_accessor :id
75
+
76
+ # @return [Model::TYPE_POINTER]
77
+ def __type; Parse::Model::TYPE_POINTER; end
78
+
79
+ alias_method :className, :parse_class
80
+ # A Parse object as a className field and objectId. In ruby, we will use the
81
+ # id attribute method, but for usability, we will also alias it to objectId
82
+ alias_method :objectId, :id
83
+
84
+ # A Parse pointer only requires the name of the remote Parse collection name,
85
+ # and the `objectId` of the record.
86
+ # @param table [String] The Parse class name in the Parse database.
87
+ # @param oid [String] The objectId
88
+ def initialize(table, oid)
89
+ @parse_class = table.to_s
90
+ @id = oid.to_s
91
+ end
90
92
 
91
- # @return [String] the name of the collection for this Pointer.
92
- def parse_class
93
- @parse_class
94
- end
93
+ # @return [String] the name of the collection for this Pointer.
94
+ def parse_class
95
+ @parse_class
96
+ end
95
97
 
96
- # @return [String] a string representing the class and id of this instance.
97
- def sig
98
- "#{@parse_class}##{id || 'new'}"
99
- end
98
+ # @return [String] a string representing the class and id of this instance.
99
+ def sig
100
+ "#{@parse_class}##{id || "new"}"
101
+ end
100
102
 
101
- # @return [Hash]
102
- def attributes
103
- ATTRIBUTES
104
- end
103
+ # @return [Hash]
104
+ def attributes
105
+ ATTRIBUTES
106
+ end
105
107
 
106
- # @return [Hash] serialized JSON structure
107
- def json_hash
108
- JSON.parse to_json
109
- end
108
+ # @return [Hash] serialized JSON structure
109
+ def json_hash
110
+ JSON.parse to_json
111
+ end
110
112
 
111
- # Create a new pointer with the current class name and id. While this may not make sense
112
- # for a pointer instance, Parse::Object subclasses use this inherited method to turn themselves into
113
- # pointer objects.
114
- # @example
115
- # user = Parse::User.first
116
- # user.pointer # => Parse::Pointer("_User", user.id)
117
- #
118
- # @return [Pointer] a new Pointer for this object.
119
- # @see Parse::Object
120
- def pointer
121
- Pointer.new parse_class, @id
122
- end
113
+ # Create a new pointer with the current class name and id. While this may not make sense
114
+ # for a pointer instance, Parse::Object subclasses use this inherited method to turn themselves into
115
+ # pointer objects.
116
+ # @example
117
+ # user = Parse::User.first
118
+ # user.pointer # => Parse::Pointer("_User", user.id)
119
+ #
120
+ # @return [Pointer] a new Pointer for this object.
121
+ # @see Parse::Object
122
+ def pointer
123
+ Pointer.new parse_class, @id
124
+ end
123
125
 
124
- # Whether this instance is in pointer state. A pointer is determined
125
- # if we have a parse class and an id, but no created_at or updated_at fields.
126
- # @return [Boolean] true if instance is in pointer state.
127
- def pointer?
128
- present? && @created_at.blank? && @updated_at.blank?
129
- end
126
+ # Whether this instance is in pointer state. A pointer is determined
127
+ # if we have a parse class and an id, but no created_at or updated_at fields.
128
+ # @return [Boolean] true if instance is in pointer state.
129
+ def pointer?
130
+ present? && @created_at.blank? && @updated_at.blank?
131
+ end
130
132
 
131
- # Returns true if the data for this instance has been fetched. Because of some autofetching
132
- # mechanisms, this is useful to know whether the object already has data without actually causing
133
- # a fetch of the data.
134
- # @return [Boolean] true if not in pointer state.
135
- def fetched?
136
- present? && pointer? == false
137
- end
133
+ # Returns true if the data for this instance has been fetched. Because of some autofetching
134
+ # mechanisms, this is useful to know whether the object already has data without actually causing
135
+ # a fetch of the data.
136
+ # @return [Boolean] true if not in pointer state.
137
+ def fetched?
138
+ present? && pointer? == false
139
+ end
138
140
 
139
- # This method is a general implementation that gets overriden by Parse::Object subclass.
140
- # Given the class name and the id, we will go to Parse and fetch the actual record, returning the
141
- # JSON object.
142
- # @return [Parse::Object] the fetched Parse::Object, nil otherwise.
143
- def fetch
144
- response = client.fetch_object(parse_class, id)
145
- return nil if response.error?
146
- response.result
147
- end
141
+ # This method is a general implementation that gets overriden by Parse::Object subclass.
142
+ # Given the class name and the id, we will go to Parse and fetch the actual record, returning the
143
+ # JSON object.
144
+ # @return [Parse::Object] the fetched Parse::Object, nil otherwise.
145
+ def fetch
146
+ response = client.fetch_object(parse_class, id)
147
+ return nil if response.error?
148
+ response.result
149
+ end
148
150
 
149
- # Two Parse::Pointers (or Parse::Objects) are equal if both of them have
150
- # the same Parse class and the same id.
151
- # @return [Boolean]
152
- def ==(o)
153
- return false unless o.is_a?(Pointer)
154
- #only equal if the Parse class and object ID are the same.
155
- self.parse_class == o.parse_class && id == o.id
156
- end
157
- alias_method :eql?, :==
158
-
159
- # Compute a hash-code for this object. It is calculated
160
- # by combining the Parse class name, the {Parse::Object#id} field and
161
- # any pending changes.
162
- #
163
- # Two objects with the same content will have the same hash code
164
- # (and will compare using eql?).
165
- # @return [Fixnum]
166
- def hash
167
- "#{parse_class}#{id}#{changes.to_s}".hash
168
- end
151
+ # Two Parse::Pointers (or Parse::Objects) are equal if both of them have
152
+ # the same Parse class and the same id.
153
+ # @return [Boolean]
154
+ def ==(o)
155
+ return false unless o.is_a?(Pointer)
156
+ #only equal if the Parse class and object ID are the same.
157
+ self.parse_class == o.parse_class && id == o.id
158
+ end
169
159
 
170
- # @return [Boolean] true if instance has a Parse class and an id.
171
- def present?
172
- parse_class.present? && @id.present?
173
- end
160
+ alias_method :eql?, :==
174
161
 
175
- # Access the pointer properties through hash accessor. This is done for
176
- # compatibility with the hash access of a Parse::Object. This method
177
- # returns nil if the key is not one of: :id, :objectId, or :className.
178
- # @param key [String] the name of the property.
179
- # @return [Object] the value for this key.
180
- def [](key)
181
- return nil unless [:id,:objectId,:className].include?(key.to_sym)
182
- send(key)
183
- end
162
+ # Compute a hash-code for this object. It is calculated
163
+ # by combining the Parse class name, the {Parse::Object#id} field and
164
+ # any pending changes.
165
+ #
166
+ # Two objects with the same content will have the same hash code
167
+ # (and will compare using eql?).
168
+ # @return [Fixnum]
169
+ def hash
170
+ "#{parse_class}#{id}#{changes.to_s}".hash
171
+ end
184
172
 
185
- # Set the pointer properties through hash accessor. This is done for
186
- # compatibility with the hash access of a Parse::Object. This method
187
- # does nothing if the key is not one of: :id, :objectId, or :className.
188
- # @param key (see #[])
189
- # @return [Object]
190
- def []=(key,value)
191
- return unless [:id,:objectId,:className].include?(key.to_sym)
192
- send("#{key}=",value)
193
- end
173
+ # @return [Boolean] true if instance has a Parse class and an id.
174
+ def present?
175
+ parse_class.present? && @id.present?
176
+ end
194
177
 
178
+ # Access the pointer properties through hash accessor. This is done for
179
+ # compatibility with the hash access of a Parse::Object. This method
180
+ # returns nil if the key is not one of: :id, :objectId, or :className.
181
+ # @param key [String] the name of the property.
182
+ # @return [Object] the value for this key.
183
+ def [](key)
184
+ return nil unless [:id, :objectId, :className].include?(key.to_sym)
185
+ send(key)
195
186
  end
196
187
 
188
+ # Set the pointer properties through hash accessor. This is done for
189
+ # compatibility with the hash access of a Parse::Object. This method
190
+ # does nothing if the key is not one of: :id, :objectId, or :className.
191
+ # @param key (see #[])
192
+ # @return [Object]
193
+ def []=(key, value)
194
+ return unless [:id, :objectId, :className].include?(key.to_sym)
195
+ send("#{key}=", value)
196
+ end
197
+ end
197
198
  end
198
199
 
199
200
  # extensions
@@ -1,9 +1,10 @@
1
1
  # encoding: UTF-8
2
2
  # frozen_string_literal: true
3
3
 
4
- require_relative '../query.rb'
5
- require_relative '../client.rb'
6
- require 'active_model_serializers'
4
+ require_relative "../query.rb"
5
+ require_relative "../client.rb"
6
+ require "active_model_serializers"
7
+
7
8
  module Parse
8
9
  # This class represents the API to send push notification to devices that are
9
10
  # available in the Installation table. Push notifications are implemented
@@ -68,7 +69,7 @@ module Parse
68
69
  # @!attribute [rw] channels
69
70
  # @return [Array] an array of strings for subscribed channels.
70
71
  attr_accessor :query, :alert, :badge, :sound, :title, :data,
71
- :expiration_time, :expiration_interval, :push_time, :channels
72
+ :expiration_time, :expiration_interval, :push_time, :channels
72
73
 
73
74
  alias_method :message, :alert
74
75
  alias_method :message=, :alert=
@@ -134,14 +135,13 @@ module Parse
134
135
  msg = {
135
136
  data: {
136
137
  alert: alert,
137
- badge: badge || "Increment"
138
- }
138
+ badge: badge || "Increment",
139
+ },
139
140
  }
140
141
  msg[:data][:sound] = sound if sound.present?
141
142
  msg[:data][:title] = title if title.present?
142
143
  msg[:data].merge! @data if @data.is_a?(Hash)
143
144
 
144
-
145
145
  if @expiration_time.present?
146
146
  msg[:expiration_time] = @expiration_time.respond_to?(:iso8601) ? @expiration_time.iso8601(3) : @expiration_time
147
147
  end
@@ -170,9 +170,7 @@ module Parse
170
170
  def send(message = nil)
171
171
  @alert = message if message.is_a?(String)
172
172
  @data = message if message.is_a?(Hash)
173
- client.push( payload.as_json )
173
+ client.push(payload.as_json)
174
174
  end
175
-
176
175
  end
177
-
178
176
  end
@@ -1,5 +1,4 @@
1
-
2
- require_relative 'object'
1
+ require_relative "object"
3
2
 
4
3
  # Simple include to use short verion of core class names
5
4
  ::Installation = Parse::Installation unless defined?(::Installation)
@@ -1,8 +1,8 @@
1
1
  # encoding: UTF-8
2
2
  # frozen_string_literal: true
3
3
 
4
- require 'active_support'
5
- require 'active_support/values/time_zone'
4
+ require "active_support"
5
+ require "active_support/values/time_zone"
6
6
  require_relative "model"
7
7
 
8
8
  module Parse
@@ -118,7 +118,7 @@ module Parse
118
118
  @name = timezone
119
119
  @zone = nil
120
120
  else
121
- raise ArgumentError, 'Invalid value passed to Parse::TimeZone#zone.'
121
+ raise ArgumentError, "Invalid value passed to Parse::TimeZone#zone."
122
122
  end
123
123
  end
124
124
 
@@ -137,7 +137,5 @@ module Parse
137
137
  def valid?
138
138
  ActiveSupport::TimeZone[to_s].present?
139
139
  end
140
-
141
140
  end
142
-
143
141
  end