parse-stack 1.3.7 → 1.3.8
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +2 -0
- data/Changes.md +15 -7
- data/Gemfile.lock +12 -12
- data/README.md +151 -9
- data/Rakefile +5 -0
- data/bin/console +3 -0
- data/lib/parse/api/config.rb +5 -0
- data/lib/parse/client.rb +66 -35
- data/lib/parse/client/body_builder.rb +3 -3
- data/lib/parse/client/request.rb +12 -2
- data/lib/parse/client/response.rb +6 -3
- data/lib/parse/model/model.rb +1 -1
- data/lib/parse/query/constraint.rb +37 -30
- data/lib/parse/query/constraints.rb +77 -23
- data/lib/parse/stack/version.rb +1 -1
- data/lib/parse/webhooks.rb +1 -1
- data/parse-stack.gemspec +9 -11
- metadata +3 -10
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 18eab2bb5c64686e9b7713d4083db00fd5b7d026
|
4
|
+
data.tar.gz: 21cc6c542518c284edcd90c8ff8c09df4883dd30
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 38a5decb6fbbb89caa454ac583ea9cfbad0929a59bbfa78b86befc00bb53a861f040951ce9bb6013a6b03bb0fb086bd98438c00927da2030a66cb57798159858
|
7
|
+
data.tar.gz: 8c16ed21c5c450270382d8223d010978de8950cbd9cfaf3172d2915f1e81d73a151b55176b61e41f1fbd662fa6a8c1554e620650c9a92aec84cdb26446fd26b3
|
data/.gitignore
CHANGED
data/Changes.md
CHANGED
@@ -1,12 +1,21 @@
|
|
1
1
|
# Parse-Stack Changes
|
2
2
|
|
3
|
+
1.3.8
|
4
|
+
-----------
|
5
|
+
- Support for reloading the Parse config data with `Parse.config!`.
|
6
|
+
- The Parse::Request object is now provided in the Parse::Response instance.
|
7
|
+
- The HTTP status code is provided in `http_status` accessor for a Parse::Response.
|
8
|
+
- Raised errors now provide info on the request that failed.
|
9
|
+
- Added new `ServiceUnavailableError` exception for Parse error code 2 and HTTP 503 errors.
|
10
|
+
- Upon a `ServiceUnavailableError`, we will retry the request one more time after 2 seconds.
|
11
|
+
- `:not_in` and `:contains_all` queries will format scalar values into an array.
|
12
|
+
- `:exists` and `:null` will raise `ParseConstraintError` if non-boolean values are passed.
|
13
|
+
- NEW: `:id` constraint to allow passing an objectId to a query where we will infer the class.
|
14
|
+
|
3
15
|
1.3.7
|
4
16
|
-----------
|
5
17
|
- Fixes json_api loading issue between ruby json and active_model_serializers.
|
6
18
|
- Fixes loading active_support core extensions.
|
7
|
-
|
8
|
-
1.3.5
|
9
|
-
-----------
|
10
19
|
- Support for passing a `:session_token` as part of a Parse::Query.
|
11
20
|
- Default mime-type for Parse::File instances is `image/jpeg`. You can override the default by setting
|
12
21
|
`Parse::File.default_mime_type`.
|
@@ -19,10 +28,9 @@
|
|
19
28
|
- Added `$within` => `$box` GeoPoint query. (see documentation)
|
20
29
|
- Improves support when using Parse-Server.
|
21
30
|
- Major documentation updates.
|
22
|
-
- `limit` no longer defaults to 100 in `Parse::Query`. This will allow Parse-Server to determine default limit, if any.
|
23
|
-
- `:bool` property type has been added as an alias to `:boolean`.
|
24
|
-
- You can turn off formatting field names with `Parse::Query.field_formatter = nil`.
|
25
|
-
|
31
|
+
- `limit` no longer defaults to 100 in `Parse::Query`. This will allow Parse-Server to determine default limit, if any.
|
32
|
+
- `:bool` property type has been added as an alias to `:boolean`.
|
33
|
+
- You can turn off formatting field names with `Parse::Query.field_formatter = nil`.
|
26
34
|
|
27
35
|
1.3.1
|
28
36
|
-----------
|
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
parse-stack (1.3.
|
4
|
+
parse-stack (1.3.8)
|
5
5
|
active_model_serializers (>= 0.9, < 1)
|
6
6
|
activemodel (>= 4.2.1, < 6)
|
7
7
|
activesupport (>= 4.2.1, < 6)
|
@@ -14,15 +14,15 @@ PATH
|
|
14
14
|
GEM
|
15
15
|
remote: https://rubygems.org/
|
16
16
|
specs:
|
17
|
-
actionpack (5.0.0)
|
18
|
-
actionview (= 5.0.0)
|
19
|
-
activesupport (= 5.0.0)
|
17
|
+
actionpack (5.0.0.1)
|
18
|
+
actionview (= 5.0.0.1)
|
19
|
+
activesupport (= 5.0.0.1)
|
20
20
|
rack (~> 2.0)
|
21
21
|
rack-test (~> 0.6.3)
|
22
22
|
rails-dom-testing (~> 2.0)
|
23
23
|
rails-html-sanitizer (~> 1.0, >= 1.0.2)
|
24
|
-
actionview (5.0.0)
|
25
|
-
activesupport (= 5.0.0)
|
24
|
+
actionview (5.0.0.1)
|
25
|
+
activesupport (= 5.0.0.1)
|
26
26
|
builder (~> 3.1)
|
27
27
|
erubis (~> 2.7.0)
|
28
28
|
rails-dom-testing (~> 2.0)
|
@@ -32,9 +32,9 @@ GEM
|
|
32
32
|
activemodel (>= 4.1, < 6)
|
33
33
|
jsonapi (~> 0.1.1.beta2)
|
34
34
|
railties (>= 4.1, < 6)
|
35
|
-
activemodel (5.0.0)
|
36
|
-
activesupport (= 5.0.0)
|
37
|
-
activesupport (5.0.0)
|
35
|
+
activemodel (5.0.0.1)
|
36
|
+
activesupport (= 5.0.0.1)
|
37
|
+
activesupport (5.0.0.1)
|
38
38
|
concurrent-ruby (~> 1.0, >= 1.0.2)
|
39
39
|
i18n (~> 0.7)
|
40
40
|
minitest (~> 5.1)
|
@@ -85,9 +85,9 @@ GEM
|
|
85
85
|
nokogiri (~> 1.6.0)
|
86
86
|
rails-html-sanitizer (1.0.3)
|
87
87
|
loofah (~> 2.0)
|
88
|
-
railties (5.0.0)
|
89
|
-
actionpack (= 5.0.0)
|
90
|
-
activesupport (= 5.0.0)
|
88
|
+
railties (5.0.0.1)
|
89
|
+
actionpack (= 5.0.0.1)
|
90
|
+
activesupport (= 5.0.0.1)
|
91
91
|
method_source
|
92
92
|
rake (>= 0.8.7)
|
93
93
|
thor (>= 0.18.1, < 2.0)
|
data/README.md
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
# Parse-Stack - A Parse-Server Ruby Client and ORM
|
2
|
-
Parse
|
2
|
+
Parse-Stack is a [Parse Server](https://github.com/ParsePlatform/parse-server) REST API Client and ORM framework for ruby. It provides a client adapter, a query engine, an object relational mapper (ORM) and a Cloud Code Webhooks rack application.
|
3
3
|
|
4
4
|
### Code Status
|
5
5
|
[![Gem Version](https://badge.fury.io/rb/parse-stack.svg)](https://badge.fury.io/rb/parse-stack)
|
@@ -17,8 +17,10 @@ Parse Stack is an opinionated framework for ruby applications that utilize the [
|
|
17
17
|
- [Parse::Query](#parsequery)
|
18
18
|
- [Parse::Object](#parseobject)
|
19
19
|
- [Parse::Webhooks](#parsewebhooks)
|
20
|
+
- [Field Naming Conventions](#field-naming-conventions)
|
20
21
|
- [Connection Setup](#connection-setup)
|
21
22
|
- [Connection Options](#connection-options)
|
23
|
+
- [Parse Config](#parse-config)
|
22
24
|
- [Core Classes](#core-classes)
|
23
25
|
- [Parse::Pointer](#parsepointer)
|
24
26
|
- [Parse::File](#parsefile)
|
@@ -26,6 +28,10 @@ Parse Stack is an opinionated framework for ruby applications that utilize the [
|
|
26
28
|
- [Parse::GeoPoint](#parsegeopoint)
|
27
29
|
- [Calculating Distances between locations](#calculating-distances-between-locations)
|
28
30
|
- [Parse::Bytes](#parsebytes)
|
31
|
+
- [Parse::User](#parseuser)
|
32
|
+
- [Parse::Installation](#parseinstallation)
|
33
|
+
- [Parse::Session](#parsesession)
|
34
|
+
- [Parse::Role](#parserole)
|
29
35
|
- [Modeling and Subclassing](#modeling-and-subclassing)
|
30
36
|
- [Defining Properties](#defining-properties)
|
31
37
|
- [Accessor Aliasing](#accessor-aliasing)
|
@@ -73,6 +79,7 @@ Parse Stack is an opinionated framework for ruby applications that utilize the [
|
|
73
79
|
- [Reject](#reject)
|
74
80
|
- [Matches Query](#matches-query)
|
75
81
|
- [Excludes Query](#excludes-query)
|
82
|
+
- [Matches Object Id](#matches-object-id)
|
76
83
|
- [Geo Queries](#geo-queries)
|
77
84
|
- [Max Distance Constraint](#max-distance-constraint)
|
78
85
|
- [Bounding Box Constraint](#bounding-box-constraint)
|
@@ -119,16 +126,27 @@ class Song < Parse::Object
|
|
119
126
|
has_many :likes, as: :user, through: :relation
|
120
127
|
end
|
121
128
|
|
122
|
-
|
123
|
-
|
129
|
+
class Artist < Parse::Object
|
130
|
+
property :name
|
131
|
+
property :genres, :array
|
132
|
+
end
|
133
|
+
|
134
|
+
# updates schemas for your Parse app based on your models (non-destructive)
|
135
|
+
Parse.auto_upgrade!
|
124
136
|
|
137
|
+
artist = Artist.new(name: "Frank Sinatra", genres: ["swing", "jazz"])
|
138
|
+
artist.save
|
139
|
+
|
140
|
+
# Query
|
125
141
|
artist = Artist.first(:name.like => /Sinatra/, :genres.in => ['swing'])
|
126
142
|
|
143
|
+
# more examples
|
127
144
|
song = Song.new name: "Fly Me to the Moon"
|
128
145
|
song.artist = artist
|
129
|
-
# Parse files
|
146
|
+
# Parse files - upload a file and attach to object
|
130
147
|
song.audio_file = Parse::File.create("http://path_to.mp3")
|
131
|
-
|
148
|
+
|
149
|
+
# relations - find a User matching username and add it to relation.
|
132
150
|
song.likes.add Parse::User.first(username: "persaud")
|
133
151
|
|
134
152
|
# saves both attributes and relations
|
@@ -149,6 +167,7 @@ result = Parse.call_function :myFunctionName, {param: value}
|
|
149
167
|
## Main Features
|
150
168
|
While there are many additional features of the framework, these are the main points.
|
151
169
|
|
170
|
+
- Support for all Parse Query constraints.
|
152
171
|
- Object Relational Mapping with dirty tracking.
|
153
172
|
- Easy management of Parse GeoPoints, Files and ACLs.
|
154
173
|
- Parse Queries support with caching middleware. (Reduces API usage)
|
@@ -253,6 +272,19 @@ Sets the default cache expiration time (in seconds) for successful non-empty `GE
|
|
253
272
|
#### `:faraday`
|
254
273
|
You may pass a hash of options that will be passed to the `Faraday` constructor.
|
255
274
|
|
275
|
+
## Parse Config
|
276
|
+
Getting your configuration variables once you have a default client setup can be done with `Parse.config`. The first time this method is called, Parse-Stack will get the configuration from Parse-Server, and cache it. To force a reload of the config, use `config!`.
|
277
|
+
|
278
|
+
```ruby
|
279
|
+
Parse.setup( ... )
|
280
|
+
|
281
|
+
val = Parse.config["myKey"]
|
282
|
+
val = Parse.config["myKey"] # cached
|
283
|
+
|
284
|
+
# Force fetch of config!
|
285
|
+
val = Parse.config!["myKey"]
|
286
|
+
|
287
|
+
```
|
256
288
|
|
257
289
|
## Core Classes
|
258
290
|
While some native data types are similar to the ones supported by Ruby natively, other ones are more complex and require their dedicated classes.
|
@@ -381,6 +413,63 @@ The `Bytes` data type represents the storage format for binary content in a Pars
|
|
381
413
|
decoded = bytes.decoded # same as Base64.decode64
|
382
414
|
```
|
383
415
|
|
416
|
+
### Parse::User
|
417
|
+
This class represents the data and columns contained in the standard Parse `_User` collection. You may add additional properties and methods to this class. It is defined as follows:
|
418
|
+
|
419
|
+
```ruby
|
420
|
+
class Parse::User < Parse::Object
|
421
|
+
property :auth_data, :object
|
422
|
+
property :email
|
423
|
+
property :password
|
424
|
+
property :username
|
425
|
+
end
|
426
|
+
```
|
427
|
+
|
428
|
+
### Parse::Installation
|
429
|
+
This class represents the data and columns contained in the standard Parse `_Installation` collection. You may add additional properties and methods to this class. It is defined as follows:
|
430
|
+
|
431
|
+
```ruby
|
432
|
+
class Parse::Installation < Parse::Object
|
433
|
+
property :channels, :array
|
434
|
+
property :gcm_sender_id, :string, field: :GCMSenderId
|
435
|
+
property :badge, :integer
|
436
|
+
property :installation_id
|
437
|
+
property :device_token
|
438
|
+
property :device_type
|
439
|
+
property :locale_identifier
|
440
|
+
property :push_type
|
441
|
+
property :time_zone
|
442
|
+
end
|
443
|
+
```
|
444
|
+
|
445
|
+
### Parse::Session
|
446
|
+
This class represents the data and columns contained in the standard Parse `_Session` collection. You may add additional properties and methods to this class. It is defined as follows:
|
447
|
+
|
448
|
+
```ruby
|
449
|
+
class Parse::Session < Parse::Object
|
450
|
+
property :created_with, :object
|
451
|
+
property :expires_at, :date
|
452
|
+
property :installation_id
|
453
|
+
property :restricted, :boolean
|
454
|
+
property :session_token
|
455
|
+
|
456
|
+
belongs_to :user
|
457
|
+
end
|
458
|
+
```
|
459
|
+
|
460
|
+
### Parse::Role
|
461
|
+
This class represents the data and columns contained in the standard Parse `_Role` collection. You may add additional properties and methods to this class. It is defined as follows:
|
462
|
+
|
463
|
+
```ruby
|
464
|
+
class Parse::Role < Parse::Object
|
465
|
+
property :name
|
466
|
+
|
467
|
+
has_many :roles, through: :relation
|
468
|
+
has_many :users, through: :relation
|
469
|
+
end
|
470
|
+
```
|
471
|
+
|
472
|
+
|
384
473
|
## Modeling and Subclassing
|
385
474
|
For the general case, your Parse classes should inherit from `Parse::Object`. `Parse::Object` utilizes features from `ActiveModel` to add several features to each instance of your subclass. These include `Dirty`, `Conversion`, `Callbacks`, `Naming` and `Serializers::JSON`.
|
386
475
|
|
@@ -1134,6 +1223,17 @@ q.where :field => value
|
|
1134
1223
|
# (alias) :field.eq => value
|
1135
1224
|
```
|
1136
1225
|
|
1226
|
+
If you want to see if a particular field contains a specific Parse::Object (pointer), you can use the following:
|
1227
|
+
|
1228
|
+
```ruby
|
1229
|
+
# find rows where the `field` contains a Parse "_User" pointer with the specified objectId.
|
1230
|
+
q.where :field => Parse::Pointer.new("_User", "anObjectId")
|
1231
|
+
# alias using subclass helper
|
1232
|
+
q.where :field => Parse::User.pointer("anObjectId")
|
1233
|
+
# alias using `:id` constraint. We will infer :user maps to class "_User" (Parse::User)
|
1234
|
+
q.where :user.id => "anObjectId"
|
1235
|
+
```
|
1236
|
+
|
1137
1237
|
#### Less Than
|
1138
1238
|
Equivalent to the `$lt` Parse query operation. The alias `before` is provided for readability.
|
1139
1239
|
|
@@ -1196,7 +1296,7 @@ q.where :field.exists => true|false
|
|
1196
1296
|
```
|
1197
1297
|
|
1198
1298
|
#### Contained In
|
1199
|
-
Equivalent to the `$in` Parse query operation. Checks whether the value in the column field is contained in the set of values in the array.
|
1299
|
+
Equivalent to the `$in` Parse query operation. Checks whether the value in the column field is contained in the set of values in the target array. If the field is an array data type, it checks whether at least one value in the field array is contained in the set of values in the target array.
|
1200
1300
|
|
1201
1301
|
```ruby
|
1202
1302
|
# ex. :score.in => [1,3,5,7,9]
|
@@ -1206,7 +1306,7 @@ q.where :field.contained_in => [item1,item2,...]
|
|
1206
1306
|
```
|
1207
1307
|
|
1208
1308
|
#### Not Contained In
|
1209
|
-
Equivalent to the `$nin` Parse query operation. Checks whether the value in the column field is __not__ contained in the set of values in the array.
|
1309
|
+
Equivalent to the `$nin` Parse query operation. Checks whether the value in the column field is __not__ contained in the set of values in the target array. If the field is an array data type, it checks whether at least one value in the field array is __not__ contained in the set of values in the target array.
|
1210
1310
|
|
1211
1311
|
```ruby
|
1212
1312
|
# ex. :player_name.not_in => ['Jonathan', 'Dario', 'Shawn']
|
@@ -1216,7 +1316,7 @@ q.where :field.not_contained_in => [item1,item2,...]
|
|
1216
1316
|
```
|
1217
1317
|
|
1218
1318
|
#### Contains All
|
1219
|
-
Equivalent to the `$all` Parse query operation. Checks whether the value in the column field contains all of the given values provided in the array. Note that the `field` column
|
1319
|
+
Equivalent to the `$all` Parse query operation. Checks whether the value in the column field contains all of the given values provided in the array. Note that the `field` column should be of type `Array` in your Parse class.
|
1220
1320
|
|
1221
1321
|
```ruby
|
1222
1322
|
# ex. :array_key.all => [2,3,4]
|
@@ -1283,6 +1383,48 @@ q.where :field.excludes => query
|
|
1283
1383
|
q.where :field.not_in_query => query # alias
|
1284
1384
|
```
|
1285
1385
|
|
1386
|
+
#### Matches Object Id
|
1387
|
+
Sometimes you want to find rows where a particular Parse object exists. You can do so by passing a the Parse::Object subclass, a Parse::Pointer. You can also use the `id` constraint. This will assume that the name of the field matches a particular Parse class you have defined. Assume the following:
|
1388
|
+
|
1389
|
+
```ruby
|
1390
|
+
# where this Parse object equals the object in the column `field`.
|
1391
|
+
q.where :field => Parse::Pointer("Field", "someObjectId")
|
1392
|
+
# alias, shorthand when we infer `:field` maps to `Field` parse class.
|
1393
|
+
q.where :field.id => "someObjectId"
|
1394
|
+
# "field":{"__type":"Pointer","className":"Field","objectId":"someObjectId"}}
|
1395
|
+
|
1396
|
+
```
|
1397
|
+
|
1398
|
+
##### Additional Examples
|
1399
|
+
|
1400
|
+
```ruby
|
1401
|
+
|
1402
|
+
class Artist < Parse::Object
|
1403
|
+
# as described before
|
1404
|
+
end
|
1405
|
+
|
1406
|
+
class Song < Parse::Object
|
1407
|
+
belongs_to :artist
|
1408
|
+
end
|
1409
|
+
|
1410
|
+
artist = Artist.first # get any artist
|
1411
|
+
artist_id = artist.id # ex. artist.id
|
1412
|
+
|
1413
|
+
# find all songs for this artist object
|
1414
|
+
Song.all :artist => artist
|
1415
|
+
```
|
1416
|
+
|
1417
|
+
In some cases, you do not have the Parse object, but you have its `objectId`. You can use the objectId in the query as follows:
|
1418
|
+
|
1419
|
+
```ruby
|
1420
|
+
# shorthand if you are using convention. Will infer class `Artist`
|
1421
|
+
Song.all :artist.id => artist_id
|
1422
|
+
|
1423
|
+
# other approaches, same result
|
1424
|
+
Song.all :artist => Artist.pointer(artist_id)
|
1425
|
+
Song.all :artist => Parse::Pointer.new("Artist", artist_id)
|
1426
|
+
```
|
1427
|
+
|
1286
1428
|
### Geo Queries
|
1287
1429
|
Equivalent to the `$nearSphere` Parse query operation. This is only applicable if the field is of type `GeoPoint`. This will query Parse and return a list of results ordered by distance with the nearest object being first.
|
1288
1430
|
|
@@ -1446,7 +1588,7 @@ Push notifications are implemented through the `Parse::Push` class. To send push
|
|
1446
1588
|
```
|
1447
1589
|
|
1448
1590
|
## Cloud Code Webhooks
|
1449
|
-
Parse Parse allows you to receive Cloud Code webhooks on your own hosted server. The `Parse::Webhooks` class is a lightweight Rack application that routes incoming Cloud Code webhook requests and payloads to locally registered handlers. The payloads are `Parse::Payload` type of objects that represent that data that Parse sends webhook handlers. You can register any of the Cloud Code webhook trigger hooks (`beforeSave`, `afterSave`, `beforeDelete`, `afterDelete`) and function hooks.
|
1591
|
+
Parse Parse allows you to receive Cloud Code webhooks on your own hosted server. The `Parse::Webhooks` class is a lightweight Rack application that routes incoming Cloud Code webhook requests and payloads to locally registered handlers. The payloads are `Parse::Payload` type of objects that represent that data that Parse sends webhook handlers. You can register any of the Cloud Code webhook trigger hooks (`beforeSave`, `afterSave`, `beforeDelete`, `afterDelete`) and function hooks.
|
1450
1592
|
|
1451
1593
|
### Cloud Code functions
|
1452
1594
|
You can use the `route()` method to register handler blocks. The last value returned by the block will be returned back to the client in a success response. If `error!(value)` is called inside the block, we will return the correct Parse error response with the value you provided.
|
data/Rakefile
CHANGED
data/bin/console
CHANGED
data/lib/parse/api/config.rb
CHANGED
data/lib/parse/client.rb
CHANGED
@@ -23,6 +23,7 @@ module Parse
|
|
23
23
|
class TimeoutError < Exception; end;
|
24
24
|
class ProtocolError < Exception; end;
|
25
25
|
class ServerError < Exception; end;
|
26
|
+
class ServiceUnavailableError < Exception; end;
|
26
27
|
class AuthenticationError < Exception; end;
|
27
28
|
class RequestLimitExceededError < Exception; end;
|
28
29
|
class InvalidSessionTokenError < Exception; end;
|
@@ -32,6 +33,10 @@ module Parse
|
|
32
33
|
Parse::Client.session(s).config
|
33
34
|
end
|
34
35
|
|
36
|
+
def self.config!(s = :default)
|
37
|
+
Parse::Client.session(s).config!
|
38
|
+
end
|
39
|
+
|
35
40
|
# Main class for the client. The client class is based on a Faraday stack.
|
36
41
|
# The Faraday stack is similar to a Rack-style application in which you can define middlewares
|
37
42
|
# that will be called for each request going out and coming back in. We use this in order to setup
|
@@ -48,6 +53,8 @@ module Parse
|
|
48
53
|
include Parse::API::Batch
|
49
54
|
include Parse::API::Push
|
50
55
|
include Parse::API::Schema
|
56
|
+
RETRY_COUNT = 2
|
57
|
+
RETRY_DELAY = 3 #seconds
|
51
58
|
|
52
59
|
attr_accessor :session, :cache
|
53
60
|
attr_reader :application_id, :api_key, :master_key, :server_url
|
@@ -89,9 +96,9 @@ module Parse
|
|
89
96
|
# :host - defaults to Parse::Protocol::SERVER_URL (https://api.parse.com/1/)
|
90
97
|
def initialize(opts = {})
|
91
98
|
@server_url = opts[:server_url] || ENV["PARSE_SERVER_URL"] || Parse::Protocol::SERVER_URL
|
92
|
-
@application_id = opts[:
|
93
|
-
@api_key = opts[:api_key] || ENV["PARSE_API_KEY"]
|
94
|
-
@master_key = opts[:master_key] || ENV["PARSE_MASTER_KEY"]
|
99
|
+
@application_id = opts[:application_id] || opts[:app_id] || ENV["PARSE_APP_ID"] || ENV['PARSE_SERVER_APPLICATION_ID']
|
100
|
+
@api_key = opts[:api_key] || opts[:rest_api_key] || ENV["PARSE_API_KEY"] || ENV["PARSE_REST_API_KEY"]
|
101
|
+
@master_key = opts[:master_key] || ENV["PARSE_MASTER_KEY"] || ENV['PARSE_SERVER_MASTER_KEY']
|
95
102
|
opts[:adapter] ||= Faraday.default_adapter
|
96
103
|
opts[:expires] ||= 3
|
97
104
|
if @application_id.nil? || ( @api_key.nil? && @master_key.nil? )
|
@@ -142,6 +149,10 @@ module Parse
|
|
142
149
|
self
|
143
150
|
end
|
144
151
|
|
152
|
+
def app_id
|
153
|
+
@application_id
|
154
|
+
end
|
155
|
+
|
145
156
|
def url_prefix
|
146
157
|
@session.url_prefix
|
147
158
|
end
|
@@ -160,15 +171,19 @@ module Parse
|
|
160
171
|
# with the header: paramter (also a hash).
|
161
172
|
# This method also takes in a Parse::Request object instead of the arguments listed above.
|
162
173
|
def request(method, uri = nil, body: nil, query: nil, headers: nil, opts: {})
|
174
|
+
retry_count ||= RETRY_COUNT
|
163
175
|
headers ||= {}
|
164
176
|
# if the first argument is a Parse::Request object, then construct it
|
177
|
+
_request = nil
|
165
178
|
if method.is_a?(Request)
|
166
|
-
|
167
|
-
method
|
168
|
-
uri
|
169
|
-
query
|
170
|
-
body
|
171
|
-
headers.merge!
|
179
|
+
_request = method
|
180
|
+
method = _request.method
|
181
|
+
uri ||= _request.path
|
182
|
+
query ||= _request.query
|
183
|
+
body ||= _request.body
|
184
|
+
headers.merge! _request.headers
|
185
|
+
else
|
186
|
+
_request = Parse::Request.new(method, uri, body: body, headers: headers, opts: opts)
|
172
187
|
end
|
173
188
|
|
174
189
|
# http method
|
@@ -196,46 +211,62 @@ module Parse
|
|
196
211
|
params = (method == :get ? query : body) || {}
|
197
212
|
# if the path does not start with the '/1/' prefix, then add it to be nice.
|
198
213
|
# actually send the request and return the body
|
199
|
-
|
200
|
-
|
214
|
+
response_env = @session.send(method, uri, params, headers)
|
215
|
+
response = response_env.body
|
216
|
+
response.request = _request
|
201
217
|
|
202
|
-
case response.
|
218
|
+
case response.http_status
|
203
219
|
when 401, 403
|
204
|
-
puts "[
|
205
|
-
raise Parse::AuthenticationError,
|
220
|
+
puts "[Parse:AuthenticationError] #{response}"
|
221
|
+
raise Parse::AuthenticationError, response
|
206
222
|
when 400, 408
|
207
|
-
|
208
|
-
|
209
|
-
raise Parse::TimeoutError,
|
223
|
+
if response.code == Parse::Response::ERROR_TIMEOUT || response.code == 143 #"net/http: timeout awaiting response headers"
|
224
|
+
puts "[Parse:TimeoutError] #{response}"
|
225
|
+
raise Parse::TimeoutError, response
|
210
226
|
end
|
211
227
|
when 404
|
212
|
-
unless
|
213
|
-
puts "[
|
214
|
-
raise Parse::ConnectionError,
|
228
|
+
unless response.object_not_found?
|
229
|
+
puts "[Parse:ConnectionError] #{response}"
|
230
|
+
raise Parse::ConnectionError, response
|
215
231
|
end
|
216
232
|
when 405, 406
|
217
|
-
puts "[
|
218
|
-
raise Parse::ProtocolError,
|
233
|
+
puts "[Parse:ProtocolError] #{response}"
|
234
|
+
raise Parse::ProtocolError, response
|
219
235
|
when 500
|
220
|
-
puts "[
|
221
|
-
raise Parse::
|
236
|
+
puts "[Parse:ServiceUnavailableError] #{response}"
|
237
|
+
raise Parse::ServiceUnavailableError, response
|
238
|
+
when 503
|
239
|
+
puts "[Parse:ServiceUnavailableError] #{response}"
|
240
|
+
raise Parse::ServiceUnavailableError, response
|
222
241
|
end
|
223
242
|
|
224
|
-
if
|
225
|
-
if
|
226
|
-
puts "[
|
227
|
-
raise Parse::
|
228
|
-
elsif
|
229
|
-
puts "[
|
230
|
-
raise Parse::
|
231
|
-
elsif
|
232
|
-
puts "[
|
233
|
-
raise Parse::
|
243
|
+
if response.error?
|
244
|
+
if response.code <= Parse::Response::ERROR_SERVICE_UNAVAILALBE
|
245
|
+
puts "[Parse:ServiceUnavailableError] #{response}"
|
246
|
+
raise Parse::ServiceUnavailableError, response
|
247
|
+
elsif response.code <= 100
|
248
|
+
puts "[Parse:ServerError] #{response}"
|
249
|
+
raise Parse::ServerError, response
|
250
|
+
elsif response.code == Parse::Response::ERROR_EXCEEDED_BURST_LIMIT
|
251
|
+
puts "[Parse:RequestLimitExceededError] #{response}"
|
252
|
+
raise Parse::RequestLimitExceededError, response
|
253
|
+
elsif response.code == 209 #Error 209: invalid session token
|
254
|
+
puts "[Parse:InvalidSessionTokenError] #{response}"
|
255
|
+
raise Parse::InvalidSessionTokenError, response
|
234
256
|
end
|
235
257
|
end
|
236
258
|
|
237
|
-
|
259
|
+
response
|
260
|
+
rescue Parse::ServiceUnavailableError => e
|
261
|
+
if retry_count > 0
|
262
|
+
puts "[Parse:ServiceUnavailableError] Retries remaining #{retry_count} : #{response.request}"
|
263
|
+
sleep RETRY_DELAY
|
264
|
+
retry_count -= 1
|
265
|
+
retry
|
266
|
+
end
|
267
|
+
raise e
|
238
268
|
rescue Faraday::Error::ClientError, Net::OpenTimeout => e
|
269
|
+
puts "[Parse:ConnectionError] Faraday/Net:OpenTimeout : #{e.message}"
|
239
270
|
raise Parse::ConnectionError, e.message
|
240
271
|
end
|
241
272
|
|
@@ -49,7 +49,7 @@ module Parse
|
|
49
49
|
# of the env
|
50
50
|
# TODO: CHECK FOR HTTP STATUS CODES
|
51
51
|
if self.class.logging
|
52
|
-
puts "[[Response ]]
|
52
|
+
puts "[[Response #{response_env[:status]}]] ----------------------------------"
|
53
53
|
puts response_env.body
|
54
54
|
puts "[[Response]] --------------------------------------\n"
|
55
55
|
end
|
@@ -59,9 +59,9 @@ module Parse
|
|
59
59
|
rescue Exception => e
|
60
60
|
r = Parse::Response.new
|
61
61
|
r.code = response_env.status
|
62
|
-
r.error = "Invalid
|
62
|
+
r.error = "Invalid response for #{env[:method]} #{env[:url]}: #{e}"
|
63
63
|
end
|
64
|
-
|
64
|
+
r.http_status = response_env[:status]
|
65
65
|
r.code ||= response_env[:status] if r.error.present?
|
66
66
|
response_env[:body] = r
|
67
67
|
end
|
data/lib/parse/client/request.rb
CHANGED
@@ -10,8 +10,10 @@ module Parse
|
|
10
10
|
def initialize(method, uri, body: nil, headers: nil, opts: {})
|
11
11
|
@tag = 0
|
12
12
|
method = method.downcase.to_sym
|
13
|
-
|
14
|
-
|
13
|
+
unless method == :get || method == :put || method == :post || method == :delete
|
14
|
+
raise "Invalid method #{method} for request : '#{uri}'"
|
15
|
+
end
|
16
|
+
self.method = method
|
15
17
|
self.path = uri
|
16
18
|
self.body = body
|
17
19
|
self.headers = headers || {}
|
@@ -39,6 +41,14 @@ module Parse
|
|
39
41
|
{method: @method.upcase, path: @path, body: @body}
|
40
42
|
end
|
41
43
|
|
44
|
+
def inspect
|
45
|
+
"#<#{self.class} @method=#{@method} @path='#{@path}'>"
|
46
|
+
end
|
47
|
+
|
48
|
+
def to_s
|
49
|
+
"#{@method.to_s.upcase} #{@path}"
|
50
|
+
end
|
51
|
+
|
42
52
|
end
|
43
53
|
|
44
54
|
end
|
@@ -9,6 +9,7 @@ module Parse
|
|
9
9
|
include Enumerable
|
10
10
|
|
11
11
|
ERROR_INTERNAL = 1
|
12
|
+
ERROR_SERVICE_UNAVAILALBE = 2
|
12
13
|
ERROR_TIMEOUT = 124
|
13
14
|
ERROR_EXCEEDED_BURST_LIMIT = 155
|
14
15
|
ERROR_OBJECT_NOT_FOUND = 101
|
@@ -18,12 +19,14 @@ module Parse
|
|
18
19
|
RESULTS = "results".freeze
|
19
20
|
COUNT = "count".freeze
|
20
21
|
# A response has a result or (a code and an error)
|
21
|
-
attr_accessor :parse_class, :code, :error, :result
|
22
|
+
attr_accessor :parse_class, :code, :error, :result, :http_status
|
23
|
+
attr_accessor :request # capture request that created result
|
22
24
|
# You can query Parse for counting objects, which may not actually have
|
23
25
|
# results.
|
24
26
|
attr_reader :count
|
25
27
|
|
26
28
|
def initialize(res = {})
|
29
|
+
@http_status = 0
|
27
30
|
@count = 0
|
28
31
|
@batch_response = false # by default, not a batch response
|
29
32
|
@result = nil
|
@@ -127,8 +130,8 @@ module Parse
|
|
127
130
|
end
|
128
131
|
|
129
132
|
def to_s
|
130
|
-
return "E-#{@code}: #{@error}" if error?
|
131
|
-
@result
|
133
|
+
return "[E-#{@code}] #{@request} : #{@error} (#{@http_status})" if error?
|
134
|
+
@result.to_json
|
132
135
|
end
|
133
136
|
|
134
137
|
end
|
data/lib/parse/model/model.rb
CHANGED
@@ -68,7 +68,7 @@ module Parse
|
|
68
68
|
return Parse::Date if str == TYPE_DATE.freeze
|
69
69
|
# return Parse::User if str == "User".freeze
|
70
70
|
# return Parse::Installation if str == "Installation".freeze
|
71
|
-
|
71
|
+
|
72
72
|
str = str.to_s
|
73
73
|
# Basically go through all Parse::Object subclasses and see who is has a parse_class
|
74
74
|
# set to this string. We will cache the results for future use.
|
@@ -22,7 +22,7 @@ module Parse
|
|
22
22
|
# it most likely is just the field name, so let's assume they want
|
23
23
|
# the default equality operation.
|
24
24
|
if operation.is_a?(Operation) == false && operation.respond_to?(:to_sym)
|
25
|
-
operation = Operation.new(operation.to_sym,
|
25
|
+
operation = Operation.new(operation.to_sym, self.class.operand)
|
26
26
|
end
|
27
27
|
@operation = operation
|
28
28
|
@value = value
|
@@ -30,15 +30,6 @@ module Parse
|
|
30
30
|
|
31
31
|
end
|
32
32
|
|
33
|
-
# Creates a new constraint given an operation and value.
|
34
|
-
def self.create(operation, value)
|
35
|
-
#default to a generic equality constraint if not passed an operation
|
36
|
-
unless operation.is_a?(Parse::Operation) && operation.valid?
|
37
|
-
return self.new(operation, value)
|
38
|
-
end
|
39
|
-
operation.constraint(value)
|
40
|
-
end
|
41
|
-
|
42
33
|
class << self
|
43
34
|
# The class attributes keep track of the Parse key (special Parse
|
44
35
|
# text symbol representing this operation. Ex. local method could be called
|
@@ -49,6 +40,18 @@ module Parse
|
|
49
40
|
# The higher the more priority it will receive.
|
50
41
|
attr_accessor :precedence
|
51
42
|
|
43
|
+
# Class access to store the default symbol operand action
|
44
|
+
attr_accessor :operand
|
45
|
+
|
46
|
+
# Creates a new constraint given an operation and value.
|
47
|
+
def create(operation, value)
|
48
|
+
#default to a generic equality constraint if not passed an operation
|
49
|
+
unless operation.is_a?(Parse::Operation) && operation.valid?
|
50
|
+
return self.new(operation, value)
|
51
|
+
end
|
52
|
+
operation.constraint(value)
|
53
|
+
end
|
54
|
+
|
52
55
|
# method to set the keyword for this Constaint (subclasses)
|
53
56
|
def contraint_keyword(k)
|
54
57
|
@key = k
|
@@ -60,6 +63,29 @@ module Parse
|
|
60
63
|
@precedence
|
61
64
|
end
|
62
65
|
|
66
|
+
# All subclasses should register their operation and themselves
|
67
|
+
# as the handler.
|
68
|
+
def register(op, klass = self)
|
69
|
+
self.operand ||= op
|
70
|
+
Operation.register op, klass
|
71
|
+
end
|
72
|
+
|
73
|
+
def formatted_value(value)
|
74
|
+
d = value
|
75
|
+
d = { __type: "Date", iso: d.utc.iso8601(3) } if d.respond_to?(:utc)
|
76
|
+
d = { __type: "Date", iso: d.iso8601(3) } if d.respond_to?(:iso8601)
|
77
|
+
d = d.pointer if d.respond_to?(:pointer) #simplified query object
|
78
|
+
d = d.to_s if d.is_a?(Regexp)
|
79
|
+
#d = d.pointer if d.is_a?(Parse::Object) #simplified query object
|
80
|
+
# d = d.compile
|
81
|
+
if d.is_a?(Parse::Query)
|
82
|
+
compiled = d.compile(encode: false, includeClassName: true)
|
83
|
+
# compiled["className"] = d.table
|
84
|
+
d = compiled
|
85
|
+
end
|
86
|
+
d
|
87
|
+
end
|
88
|
+
|
63
89
|
end
|
64
90
|
|
65
91
|
def precedence
|
@@ -70,12 +96,6 @@ module Parse
|
|
70
96
|
self.class.key
|
71
97
|
end
|
72
98
|
|
73
|
-
# All subclasses should register their operation and themselves
|
74
|
-
# as the handler.
|
75
|
-
def self.register(op, klass = self)
|
76
|
-
Operation.register op, klass
|
77
|
-
end
|
78
|
-
|
79
99
|
def operand
|
80
100
|
@operation.operand unless @operation.nil?
|
81
101
|
end
|
@@ -115,23 +135,10 @@ module Parse
|
|
115
135
|
|
116
136
|
# This method formats the value based on some specific data types.
|
117
137
|
def formatted_value
|
118
|
-
|
119
|
-
d = { __type: "Date", iso: d.utc.iso8601(3) } if d.respond_to?(:utc)
|
120
|
-
d = { __type: "Date", iso: d.iso8601(3) } if d.respond_to?(:iso8601)
|
121
|
-
d = d.pointer if d.respond_to?(:pointer) #simplified query object
|
122
|
-
d = d.to_s if d.is_a?(Regexp)
|
123
|
-
#d = d.pointer if d.is_a?(Parse::Object) #simplified query object
|
124
|
-
# d = d.compile
|
125
|
-
if d.is_a?(Parse::Query)
|
126
|
-
compiled = d.compile(encode: false, includeClassName: true)
|
127
|
-
# compiled["className"] = d.table
|
128
|
-
d = compiled
|
129
|
-
end
|
130
|
-
d
|
138
|
+
self.class.formatted_value(@value)
|
131
139
|
end
|
132
140
|
|
133
141
|
register :eq, Constraint
|
134
|
-
register :eql, Constraint
|
135
142
|
precedence 100
|
136
143
|
end
|
137
144
|
end
|
@@ -7,8 +7,38 @@ require_relative 'constraint'
|
|
7
7
|
# For more information: https://parse.com/docs/rest/guide#queries
|
8
8
|
# For more information about the query design pattern from DataMapper
|
9
9
|
# that inspired this, see http://datamapper.org/docs/find.html
|
10
|
+
class ParseConstraintError < Exception; end;
|
10
11
|
module Parse
|
11
12
|
|
13
|
+
class ObjectIdConstraint < Constraint
|
14
|
+
register :id
|
15
|
+
|
16
|
+
|
17
|
+
def build
|
18
|
+
className = operand.to_parse_class
|
19
|
+
value = formatted_value
|
20
|
+
begin
|
21
|
+
klass = className.constantize
|
22
|
+
rescue NameError => e
|
23
|
+
klass = Parse::Model.find_class className
|
24
|
+
end
|
25
|
+
|
26
|
+
unless klass.present? && klass.is_a?(Parse::Object) == false
|
27
|
+
raise ParseConstraintError, "#{self.class}: No Parse class defined for #{operand} as '#{className}'"
|
28
|
+
end
|
29
|
+
|
30
|
+
# allow symbols
|
31
|
+
value = value.to_s if value.is_a?(Symbol)
|
32
|
+
|
33
|
+
unless value.is_a?(String) && value.strip.present?
|
34
|
+
raise ParseConstraintError, "#{self.class}: value must be of string type representing a Parse object id."
|
35
|
+
end
|
36
|
+
value.strip!
|
37
|
+
return { @operation.operand => klass.pointer(value) }
|
38
|
+
end
|
39
|
+
|
40
|
+
end
|
41
|
+
|
12
42
|
class CompoundQueryConstraint < Constraint
|
13
43
|
contraint_keyword :$or
|
14
44
|
register :or
|
@@ -21,7 +51,7 @@ module Parse
|
|
21
51
|
|
22
52
|
end
|
23
53
|
|
24
|
-
class
|
54
|
+
class LessThanOrEqualConstraint < Constraint
|
25
55
|
contraint_keyword :$lte
|
26
56
|
register :lte
|
27
57
|
register :less_than_or_equal
|
@@ -42,7 +72,7 @@ module Parse
|
|
42
72
|
register :after
|
43
73
|
end
|
44
74
|
|
45
|
-
class
|
75
|
+
class GreaterThanOrEqualConstraint < Constraint
|
46
76
|
contraint_keyword :$gte
|
47
77
|
register :gte
|
48
78
|
register :greater_than_or_equal
|
@@ -51,22 +81,8 @@ module Parse
|
|
51
81
|
|
52
82
|
class NotEqualConstraint < Constraint
|
53
83
|
contraint_keyword :$ne
|
54
|
-
register :ne
|
55
84
|
register :not
|
56
|
-
|
57
|
-
|
58
|
-
# Mapps all items contained in the array
|
59
|
-
class ContainedInConstraint < Constraint
|
60
|
-
contraint_keyword :$in
|
61
|
-
register :in
|
62
|
-
register :contained_in
|
63
|
-
|
64
|
-
def build
|
65
|
-
val = formatted_value
|
66
|
-
val = [val].compact unless val.is_a?(Array)
|
67
|
-
{ @operation.operand => { key => val } }
|
68
|
-
end
|
69
|
-
|
85
|
+
register :ne
|
70
86
|
end
|
71
87
|
|
72
88
|
# Nullabiliity constraint maps $exist Parse clause a bit differently
|
@@ -81,7 +97,12 @@ module Parse
|
|
81
97
|
def build
|
82
98
|
# if nullability is equal true, then $exists should be set to false
|
83
99
|
|
84
|
-
|
100
|
+
value = formatted_value
|
101
|
+
unless value == true || value == false
|
102
|
+
raise ParseConstraintError, "#{self.class}: Non-Boolean value passed, it must be either `true` or `false`"
|
103
|
+
end
|
104
|
+
|
105
|
+
if value == true
|
85
106
|
return { @operation.operand => { key => false} }
|
86
107
|
else
|
87
108
|
#current bug in parse where if you want exists => true with geo queries
|
@@ -97,15 +118,42 @@ module Parse
|
|
97
118
|
register :exists
|
98
119
|
def build
|
99
120
|
# if nullability is equal true, then $exists should be set to false
|
100
|
-
|
121
|
+
value = formatted_value
|
122
|
+
|
123
|
+
unless value == true || value == false
|
124
|
+
raise ParseConstraintError, "#{self.class}: Non-Boolean value passed, it must be either `true` or `false`"
|
125
|
+
end
|
126
|
+
|
127
|
+
return { @operation.operand => { key => value } }
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
# Mapps all items contained in the array
|
132
|
+
class ContainedInConstraint < Constraint
|
133
|
+
contraint_keyword :$in
|
134
|
+
register :in
|
135
|
+
register :contained_in
|
136
|
+
|
137
|
+
def build
|
138
|
+
val = formatted_value
|
139
|
+
val = [val].compact unless val.is_a?(Array)
|
140
|
+
{ @operation.operand => { key => val } }
|
101
141
|
end
|
142
|
+
|
102
143
|
end
|
103
144
|
|
104
145
|
class NotContainedInConstraint < Constraint
|
105
146
|
contraint_keyword :$nin
|
106
|
-
register :nin
|
107
147
|
register :not_in
|
148
|
+
register :nin
|
108
149
|
register :not_contained_in
|
150
|
+
|
151
|
+
def build
|
152
|
+
val = formatted_value
|
153
|
+
val = [val].compact unless val.is_a?(Array)
|
154
|
+
{ @operation.operand => { key => val } }
|
155
|
+
end
|
156
|
+
|
109
157
|
end
|
110
158
|
|
111
159
|
# All Things must be contained
|
@@ -113,6 +161,12 @@ module Parse
|
|
113
161
|
contraint_keyword :$all
|
114
162
|
register :all
|
115
163
|
register :contains_all
|
164
|
+
|
165
|
+
def build
|
166
|
+
val = formatted_value
|
167
|
+
val = [val].compact unless val.is_a?(Array)
|
168
|
+
{ @operation.operand => { key => val } }
|
169
|
+
end
|
116
170
|
end
|
117
171
|
|
118
172
|
class SelectionConstraint < Constraint
|
@@ -158,14 +212,14 @@ module Parse
|
|
158
212
|
remote_field_name = res[:key] || remote_field_name
|
159
213
|
query = res[:query]
|
160
214
|
unless query.is_a?(Parse::Query)
|
161
|
-
raise "Invalid Parse::Query object provided in :query field of value: #{@operation.operand}.#{$dontSelect} => #{@value}"
|
215
|
+
raise ParseConstraintError, "Invalid Parse::Query object provided in :query field of value: #{@operation.operand}.#{$dontSelect} => #{@value}"
|
162
216
|
end
|
163
217
|
query = query.compile(encode: false, includeClassName: true)
|
164
218
|
elsif @value.is_a?(Parse::Query)
|
165
219
|
# if its a query, then assume dontSelect key is the same name as operand.
|
166
220
|
query = @value.compile(encode: false, includeClassName: true)
|
167
221
|
else
|
168
|
-
raise "Invalid `:reject` query constraint. It should follow the format: :field.reject => { key: 'key', query: '<Parse::Query>' }"
|
222
|
+
raise ParseConstraintError, "Invalid `:reject` query constraint. It should follow the format: :field.reject => { key: 'key', query: '<Parse::Query>' }"
|
169
223
|
end
|
170
224
|
{ @operation.operand => { :$dontSelect => { key: remote_field_name, query: query } } }
|
171
225
|
end
|
@@ -233,7 +287,7 @@ module Parse
|
|
233
287
|
geopoint_values = formatted_value
|
234
288
|
unless geopoint_values.is_a?(Array) && geopoint_values.count == 2 &&
|
235
289
|
geopoint_values.first.is_a?(Parse::GeoPoint) && geopoint_values.last.is_a?(Parse::GeoPoint)
|
236
|
-
raise( '[Parse::Query] Invalid query value parameter passed to `within_box` constraint. ' +
|
290
|
+
raise(ParseConstraintError, '[Parse::Query] Invalid query value parameter passed to `within_box` constraint. ' +
|
237
291
|
'Values in array must be `Parse::GeoPoint` objects and ' +
|
238
292
|
'it should be in an array format: [southwestPoint, northeastPoint]' )
|
239
293
|
end
|
data/lib/parse/stack/version.rb
CHANGED
data/lib/parse/webhooks.rb
CHANGED
@@ -214,7 +214,7 @@ module Parse
|
|
214
214
|
generic_result = Parse::Webhooks.call_route(payload.trigger_name, "*", payload)
|
215
215
|
result = generic_result if generic_result.present? && result.nil?
|
216
216
|
else
|
217
|
-
puts "[ParseWebhooks] --> Could not find mapping route for #{payload}"
|
217
|
+
puts "[ParseWebhooks] --> Could not find mapping route for #{payload.to_json}"
|
218
218
|
end
|
219
219
|
|
220
220
|
result = true if result.nil?
|
data/parse-stack.gemspec
CHANGED
@@ -34,15 +34,13 @@ Gem::Specification.new do |spec|
|
|
34
34
|
spec.add_runtime_dependency "faraday", [">= 0.8", "< 1"]
|
35
35
|
spec.add_runtime_dependency "faraday_middleware", [">= 0.9", "< 1"]
|
36
36
|
spec.add_runtime_dependency "moneta", [">= 0.7", "< 1"]
|
37
|
-
spec.add_runtime_dependency "rack",
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
** IMPORTANT **
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
UPGRADE
|
37
|
+
spec.add_runtime_dependency "rack", "< 3"
|
38
|
+
|
39
|
+
# spec.post_install_message = <<UPGRADE
|
40
|
+
#
|
41
|
+
# ** IMPORTANT **
|
42
|
+
# Parse::Webhook exception handling has changed in 1.3.0 and later.
|
43
|
+
# See guide: https://github.com/modernistik/parse-stack/wiki/Webhook-Migration-1.2.x-to-1.3.0
|
44
|
+
#
|
45
|
+
# UPGRADE
|
48
46
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: parse-stack
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.3.
|
4
|
+
version: 1.3.8
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Anthony Persaud
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-08-
|
11
|
+
date: 2016-08-23 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activemodel
|
@@ -238,14 +238,7 @@ homepage: https://github.com/modernistik/parse-stack
|
|
238
238
|
licenses:
|
239
239
|
- MIT
|
240
240
|
metadata: {}
|
241
|
-
post_install_message:
|
242
|
-
|
243
|
-
** IMPORTANT **
|
244
|
-
The limit field in a Parse::Query no longer defaults to 100, it must be explicitly set.
|
245
|
-
|
246
|
-
Parse::Webhook exception handling has changed in 1.3.0 and later.
|
247
|
-
See guide: https://github.com/modernistik/parse-stack/wiki/Webhook-Migration-1.2.x-to-1.3.0
|
248
|
-
|
241
|
+
post_install_message:
|
249
242
|
rdoc_options: []
|
250
243
|
require_paths:
|
251
244
|
- lib
|