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.
- checksums.yaml +5 -5
- data/.github/workflows/ruby.yml +36 -0
- data/.solargraph.yml +23 -0
- data/.travis.yml +6 -3
- data/Changes.md +84 -22
- data/Gemfile +14 -12
- data/Gemfile.lock +110 -60
- data/README.md +67 -24
- data/Rakefile +14 -14
- data/bin/parse-console +1 -0
- data/lib/parse/api/aggregate.rb +59 -0
- data/lib/parse/api/all.rb +2 -1
- data/lib/parse/api/analytics.rb +0 -3
- data/lib/parse/api/batch.rb +3 -5
- data/lib/parse/api/cloud_functions.rb +0 -3
- data/lib/parse/api/config.rb +0 -4
- data/lib/parse/api/files.rb +3 -7
- data/lib/parse/api/hooks.rb +4 -8
- data/lib/parse/api/objects.rb +9 -14
- data/lib/parse/api/push.rb +0 -4
- data/lib/parse/api/schema.rb +2 -6
- data/lib/parse/api/server.rb +4 -7
- data/lib/parse/api/sessions.rb +2 -5
- data/lib/parse/api/users.rb +9 -14
- data/lib/parse/client.rb +55 -50
- data/lib/parse/client/authentication.rb +29 -33
- data/lib/parse/client/batch.rb +8 -11
- data/lib/parse/client/body_builder.rb +19 -20
- data/lib/parse/client/caching.rb +23 -28
- data/lib/parse/client/protocol.rb +11 -12
- data/lib/parse/client/request.rb +4 -6
- data/lib/parse/client/response.rb +5 -7
- data/lib/parse/model/acl.rb +14 -12
- data/lib/parse/model/associations/belongs_to.rb +19 -24
- data/lib/parse/model/associations/collection_proxy.rb +328 -317
- data/lib/parse/model/associations/has_many.rb +22 -27
- data/lib/parse/model/associations/has_one.rb +7 -12
- data/lib/parse/model/associations/pointer_collection_proxy.rb +5 -13
- data/lib/parse/model/associations/relation_collection_proxy.rb +5 -9
- data/lib/parse/model/bytes.rb +8 -10
- data/lib/parse/model/classes/installation.rb +2 -4
- data/lib/parse/model/classes/product.rb +2 -5
- data/lib/parse/model/classes/role.rb +3 -5
- data/lib/parse/model/classes/session.rb +2 -5
- data/lib/parse/model/classes/user.rb +21 -17
- data/lib/parse/model/core/actions.rb +31 -46
- data/lib/parse/model/core/builder.rb +6 -6
- data/lib/parse/model/core/errors.rb +0 -1
- data/lib/parse/model/core/fetching.rb +45 -50
- data/lib/parse/model/core/properties.rb +53 -68
- data/lib/parse/model/core/querying.rb +292 -282
- data/lib/parse/model/core/schema.rb +89 -92
- data/lib/parse/model/date.rb +16 -23
- data/lib/parse/model/file.rb +171 -174
- data/lib/parse/model/geopoint.rb +12 -16
- data/lib/parse/model/model.rb +31 -37
- data/lib/parse/model/object.rb +58 -70
- data/lib/parse/model/pointer.rb +177 -176
- data/lib/parse/model/push.rb +8 -10
- data/lib/parse/model/shortnames.rb +1 -2
- data/lib/parse/model/time_zone.rb +3 -5
- data/lib/parse/query.rb +70 -37
- data/lib/parse/query/constraint.rb +4 -6
- data/lib/parse/query/constraints.rb +62 -20
- data/lib/parse/query/operation.rb +8 -11
- data/lib/parse/query/ordering.rb +45 -49
- data/lib/parse/stack.rb +15 -11
- data/lib/parse/stack/generators/rails.rb +28 -30
- data/lib/parse/stack/generators/templates/model.erb +5 -6
- data/lib/parse/stack/generators/templates/model_installation.rb +0 -1
- data/lib/parse/stack/generators/templates/model_role.rb +0 -1
- data/lib/parse/stack/generators/templates/model_session.rb +0 -1
- data/lib/parse/stack/generators/templates/model_user.rb +0 -1
- data/lib/parse/stack/generators/templates/parse.rb +9 -9
- data/lib/parse/stack/generators/templates/webhooks.rb +1 -2
- data/lib/parse/stack/railtie.rb +2 -4
- data/lib/parse/stack/tasks.rb +70 -86
- data/lib/parse/stack/version.rb +1 -1
- data/lib/parse/webhooks.rb +19 -26
- data/lib/parse/webhooks/payload.rb +26 -28
- data/lib/parse/webhooks/registration.rb +23 -31
- data/parse-stack.gemspec +28 -28
- data/parse-stack.png +0 -0
- metadata +27 -25
- data/.github/parse-ruby-sdk.png +0 -0
data/lib/parse/model/pointer.rb
CHANGED
@@ -1,199 +1,200 @@
|
|
1
1
|
# encoding: UTF-8
|
2
2
|
# frozen_string_literal: true
|
3
3
|
|
4
|
-
require
|
5
|
-
require
|
6
|
-
require
|
7
|
-
require
|
8
|
-
require
|
9
|
-
require_relative
|
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
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
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
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
93
|
+
# @return [String] the name of the collection for this Pointer.
|
94
|
+
def parse_class
|
95
|
+
@parse_class
|
96
|
+
end
|
95
97
|
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
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
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
103
|
+
# @return [Hash]
|
104
|
+
def attributes
|
105
|
+
ATTRIBUTES
|
106
|
+
end
|
105
107
|
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
108
|
+
# @return [Hash] serialized JSON structure
|
109
|
+
def json_hash
|
110
|
+
JSON.parse to_json
|
111
|
+
end
|
110
112
|
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
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
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
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
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
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
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
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
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
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
|
-
|
171
|
-
def present?
|
172
|
-
parse_class.present? && @id.present?
|
173
|
-
end
|
160
|
+
alias_method :eql?, :==
|
174
161
|
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
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
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
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
|
data/lib/parse/model/push.rb
CHANGED
@@ -1,9 +1,10 @@
|
|
1
1
|
# encoding: UTF-8
|
2
2
|
# frozen_string_literal: true
|
3
3
|
|
4
|
-
require_relative
|
5
|
-
require_relative
|
6
|
-
require
|
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
|
-
|
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(
|
173
|
+
client.push(payload.as_json)
|
174
174
|
end
|
175
|
-
|
176
175
|
end
|
177
|
-
|
178
176
|
end
|
@@ -1,8 +1,8 @@
|
|
1
1
|
# encoding: UTF-8
|
2
2
|
# frozen_string_literal: true
|
3
3
|
|
4
|
-
require
|
5
|
-
require
|
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,
|
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
|