parse-stack 1.7.3 → 1.9.1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|