parse-stack 1.5.2 → 1.5.3
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 +4 -4
- data/Changes.md +5 -0
- data/Gemfile.lock +1 -1
- data/README.md +40 -80
- data/lib/parse/api/all.rb +7 -0
- data/lib/parse/api/analytics.rb +8 -3
- data/lib/parse/api/apps.rb +29 -1
- data/lib/parse/api/batch.rb +14 -129
- data/lib/parse/api/cloud_functions.rb +9 -0
- data/lib/parse/api/config.rb +10 -1
- data/lib/parse/api/files.rb +7 -2
- data/lib/parse/api/hooks.rb +45 -2
- data/lib/parse/api/objects.rb +43 -6
- data/lib/parse/api/push.rb +6 -1
- data/lib/parse/api/schemas.rb +15 -1
- data/lib/parse/api/sessions.rb +5 -0
- data/lib/parse/api/users.rb +64 -5
- data/lib/parse/client/authentication.rb +25 -8
- data/lib/parse/client/batch.rb +206 -0
- data/lib/parse/client/body_builder.rb +12 -6
- data/lib/parse/client/caching.rb +42 -10
- data/lib/parse/client/protocol.rb +51 -46
- data/lib/parse/client/response.rb +1 -47
- data/lib/parse/client.rb +171 -42
- data/lib/parse/model/acl.rb +184 -39
- data/lib/parse/model/associations/belongs_to.rb +1 -0
- data/lib/parse/model/classes/role.rb +7 -1
- data/lib/parse/model/classes/session.rb +7 -3
- data/lib/parse/model/classes/user.rb +107 -0
- data/lib/parse/model/core/actions.rb +166 -115
- data/lib/parse/model/core/fetching.rb +105 -0
- data/lib/parse/model/core/properties.rb +40 -13
- data/lib/parse/model/core/querying.rb +123 -39
- data/lib/parse/model/core/schema.rb +22 -32
- data/lib/parse/model/object.rb +26 -20
- data/lib/parse/model/pointer.rb +1 -0
- data/lib/parse/query/constraint.rb +65 -27
- data/lib/parse/query/constraints.rb +0 -3
- data/lib/parse/query/operation.rb +33 -22
- data/lib/parse/query/ordering.rb +10 -5
- data/lib/parse/stack/generators/rails.rb +5 -1
- data/lib/parse/stack/generators/templates/model_installation.rb +1 -1
- data/lib/parse/stack/generators/templates/model_role.rb +1 -1
- data/lib/parse/stack/generators/templates/model_session.rb +2 -2
- data/lib/parse/stack/generators/templates/model_user.rb +1 -1
- data/lib/parse/stack/generators/templates/parse.rb +0 -1
- data/lib/parse/stack/railtie.rb +1 -0
- data/lib/parse/stack/tasks.rb +3 -1
- data/lib/parse/stack/version.rb +3 -1
- data/lib/parse/webhooks/registration.rb +3 -3
- data/lib/parse/webhooks.rb +88 -7
- metadata +5 -3
data/lib/parse/api/hooks.rb
CHANGED
@@ -5,58 +5,101 @@ module Parse
|
|
5
5
|
|
6
6
|
|
7
7
|
module API
|
8
|
+
# Defines the Parse webhooks interface for the Parse REST API
|
8
9
|
module Hooks
|
9
10
|
HOOKS_PREFIX = "hooks/"
|
11
|
+
# The allowed set of Parse triggers.
|
10
12
|
TRIGGER_NAMES = [:beforeSave, :afterSave, :beforeDelete, :afterDelete].freeze
|
13
|
+
|
14
|
+
# @!visibility private
|
11
15
|
def _verify_trigger(triggerName)
|
12
16
|
triggerName = triggerName.to_s.camelize(:lower).to_sym
|
13
17
|
raise ArgumentError, "Invalid trigger name #{triggerName}" unless TRIGGER_NAMES.include?(triggerName)
|
14
18
|
triggerName
|
15
19
|
end
|
16
20
|
|
21
|
+
# Fetch all defined cloud code functions.
|
22
|
+
# @return [Parse::Response]
|
17
23
|
def functions
|
18
24
|
request :get, "#{HOOKS_PREFIX}functions"
|
19
25
|
end
|
20
26
|
|
27
|
+
# Fetch information about a specific registered cloud function.
|
28
|
+
# @param functionName [String] the name of the cloud code function.
|
29
|
+
# @return [Parse::Response]
|
21
30
|
def fetch_function(functionName)
|
22
31
|
request :get, "#{HOOKS_PREFIX}functions/#{functionName}"
|
23
32
|
end
|
24
33
|
|
34
|
+
# Register a cloud code webhook function pointing to a endpoint url.
|
35
|
+
# @param functionName [String] the name of the cloud code function.
|
36
|
+
# @param url [String] the url endpoint for this cloud code function.
|
37
|
+
# @return [Parse::Response]
|
25
38
|
def create_function(functionName, url)
|
26
39
|
request :post, "#{HOOKS_PREFIX}functions", body: {functionName: functionName, url: url}
|
27
40
|
end
|
28
41
|
|
42
|
+
# Updated the endpoint url for a registered cloud code webhook function.
|
43
|
+
# @param functionName [String] the name of the cloud code function.
|
44
|
+
# @param url [String] the new url endpoint for this cloud code function.
|
45
|
+
# @return [Parse::Response]
|
29
46
|
def update_function(functionName, url)
|
30
|
-
#
|
47
|
+
# If you add _method => "PUT" to the JSON body,
|
31
48
|
# and send it as a POST request and parse will accept it as a PUT.
|
32
|
-
# They must do this because it is easier to send POST with Ajax.
|
33
49
|
request :put, "#{HOOKS_PREFIX}functions/#{functionName}", body: { url: url }
|
34
50
|
end
|
35
51
|
|
52
|
+
# Remove a registered cloud code webhook function.
|
53
|
+
# @param functionName [String] the name of the cloud code function.
|
54
|
+
# @return [Parse::Response]
|
36
55
|
def delete_function(functionName)
|
37
56
|
request :put, "#{HOOKS_PREFIX}functions/#{functionName}", body: { __op: "Delete" }
|
38
57
|
end
|
39
58
|
|
59
|
+
# Get the set of registered triggers.
|
60
|
+
# @return [Parse::Response]
|
40
61
|
def triggers
|
41
62
|
request :get, "#{HOOKS_PREFIX}triggers"
|
42
63
|
end
|
43
64
|
|
65
|
+
# Fetch information about a registered webhook trigger.
|
66
|
+
# @param triggerName [String] the name of the trigger. (ex. beforeSave, afterSave)
|
67
|
+
# @param className [String] the name of the Parse collection for the trigger.
|
68
|
+
# @return [Parse::Response]
|
69
|
+
# @see TRIGGER_NAMES
|
44
70
|
def fetch_trigger(triggerName, className)
|
45
71
|
triggerName = _verify_trigger(triggerName)
|
46
72
|
request :get, "#{HOOKS_PREFIX}triggers/#{className}/#{triggerName}"
|
47
73
|
end
|
48
74
|
|
75
|
+
# Register a new cloud code webhook trigger with an endpoint url.
|
76
|
+
# @param triggerName [String] the name of the trigger. (ex. beforeSave, afterSave)
|
77
|
+
# @param className [String] the name of the Parse collection for the trigger.
|
78
|
+
# @param url [String] the url endpoint for this webhook trigger.
|
79
|
+
# @return [Parse::Response]
|
80
|
+
# @see Parse::API::Hooks::TRIGGER_NAMES
|
49
81
|
def create_trigger(triggerName, className, url)
|
50
82
|
triggerName = _verify_trigger(triggerName)
|
51
83
|
body = {className: className, triggerName: triggerName, url: url }
|
52
84
|
request :post, "#{HOOKS_PREFIX}triggers", body: body
|
53
85
|
end
|
54
86
|
|
87
|
+
# Updated the registered endpoint for this cloud code webhook trigger.
|
88
|
+
# @param triggerName [String] the name of the trigger. (ex. beforeSave, afterSave)
|
89
|
+
# @param className [String] the name of the Parse collection for the trigger.
|
90
|
+
# @param url [String] the new url endpoint for this webhook trigger.
|
91
|
+
# @return [Parse::Response]
|
92
|
+
# @see Parse::API::Hooks::TRIGGER_NAMES
|
55
93
|
def update_trigger(triggerName, className, url)
|
56
94
|
triggerName = _verify_trigger(triggerName)
|
57
95
|
request :put, "#{HOOKS_PREFIX}triggers/#{className}/#{triggerName}", body: { url: url }
|
58
96
|
end
|
59
97
|
|
98
|
+
# Remove a registered cloud code webhook trigger.
|
99
|
+
# @param triggerName [String] the name of the trigger. (ex. beforeSave, afterSave)
|
100
|
+
# @param className [String] the name of the Parse collection for the trigger.
|
101
|
+
# @return [Parse::Response]
|
102
|
+
# @see Parse::API::Hooks::TRIGGER_NAMES
|
60
103
|
def delete_trigger(triggerName, className)
|
61
104
|
triggerName = _verify_trigger(triggerName)
|
62
105
|
request :put, "#{HOOKS_PREFIX}triggers/#{className}/#{triggerName}", body: { __op: "Delete" }
|
data/lib/parse/api/objects.rb
CHANGED
@@ -9,19 +9,25 @@ module Parse
|
|
9
9
|
module API
|
10
10
|
# REST API methods for fetching CRUD operations on Parse objects.
|
11
11
|
module Objects
|
12
|
-
|
12
|
+
# The class prefix for fetching objects.
|
13
13
|
CLASS_PATH_PREFIX = "classes/"
|
14
|
+
# The class prefix mapping for fetching objects.
|
14
15
|
PREFIX_MAP = { installation: "installations", _installation: "installations",
|
15
16
|
user: "users", _user: "users",
|
16
17
|
role: "roles", _role: "roles",
|
17
18
|
session: "sessions", _session: "sessions"
|
18
19
|
}.freeze
|
19
20
|
|
21
|
+
# @!visibility private
|
20
22
|
def self.included(base)
|
21
23
|
base.extend(ClassMethods)
|
22
24
|
end
|
23
25
|
|
24
26
|
module ClassMethods
|
27
|
+
# Get the API path for this class.
|
28
|
+
# @param className [String] the name of the Parse collection.
|
29
|
+
# @param id [String] optional objectId to add at the end of the path.
|
30
|
+
# @return [String] the API uri path
|
25
31
|
def uri_path(className, id = nil)
|
26
32
|
if className.is_a?(Parse::Pointer)
|
27
33
|
id = className.id
|
@@ -37,39 +43,70 @@ module Parse
|
|
37
43
|
|
38
44
|
end
|
39
45
|
|
46
|
+
# Get the API path for this class.
|
47
|
+
# @param className [String] the name of the Parse collection.
|
48
|
+
# @param id [String] optional objectId to add at the end of the path.
|
49
|
+
# @return [String] the API uri path
|
40
50
|
def uri_path(className, id = nil)
|
41
51
|
self.class.uri_path(className, id)
|
42
52
|
end
|
43
53
|
|
44
|
-
#
|
54
|
+
# Create an object in a collection.
|
55
|
+
# @param className [String] the name of the Parse collection.
|
56
|
+
# @param body [Hash] the body of the request.
|
57
|
+
# @param opts [Hash] additional options to pass to the {Parse::Client} request.
|
58
|
+
# @param headers [Hash] additional HTTP headers to send with the request.
|
59
|
+
# @return [Parse::Response]
|
45
60
|
def create_object(className, body = {}, headers: {}, **opts)
|
46
61
|
response = request :post, uri_path(className) , body: body, headers: headers, opts: opts
|
47
62
|
response.parse_class = className if response.present?
|
48
63
|
response
|
49
64
|
end
|
50
65
|
|
51
|
-
#
|
66
|
+
# Delete an object in a collection.
|
67
|
+
# @param className [String] the name of the Parse collection.
|
68
|
+
# @param id [String] The objectId of the record in the collection.
|
69
|
+
# @param opts [Hash] additional options to pass to the {Parse::Client} request.
|
70
|
+
# @param headers [Hash] additional HTTP headers to send with the request.
|
71
|
+
# @return [Parse::Response]
|
52
72
|
def delete_object(className, id, headers: {}, **opts)
|
53
73
|
response = request :delete, uri_path(className, id), headers: headers, opts: opts
|
54
74
|
response.parse_class = className if response.present?
|
55
75
|
response
|
56
76
|
end
|
57
77
|
|
58
|
-
#
|
78
|
+
# Fetch a specific object from a collection.
|
79
|
+
# @param className [String] the name of the Parse collection.
|
80
|
+
# @param id [String] The objectId of the record in the collection.
|
81
|
+
# @param opts [Hash] additional options to pass to the {Parse::Client} request.
|
82
|
+
# @param headers [Hash] additional HTTP headers to send with the request.
|
83
|
+
# @return [Parse::Response]
|
59
84
|
def fetch_object(className, id, headers: {}, **opts)
|
60
85
|
response = request :get, uri_path(className, id), headers: headers, opts: opts
|
61
86
|
response.parse_class = className if response.present?
|
62
87
|
response
|
63
88
|
end
|
64
89
|
|
65
|
-
#
|
90
|
+
# Fetch a set of matching objects for a query.
|
91
|
+
# @param className [String] the name of the Parse collection.
|
92
|
+
# @param query [Hash] The set of query constraints.
|
93
|
+
# @param opts [Hash] additional options to pass to the {Parse::Client} request.
|
94
|
+
# @param headers [Hash] additional HTTP headers to send with the request.
|
95
|
+
# @return [Parse::Response]
|
96
|
+
# @see Parse::Query
|
66
97
|
def find_objects(className, query = {}, headers: {}, **opts)
|
67
98
|
response = request :get, uri_path(className), query: query, headers: headers, opts: opts
|
68
99
|
response.parse_class = className if response.present?
|
69
100
|
response
|
70
101
|
end
|
71
102
|
|
72
|
-
#
|
103
|
+
# Update an object in a collection.
|
104
|
+
# @param className [String] the name of the Parse collection.
|
105
|
+
# @param id [String] The objectId of the record in the collection.
|
106
|
+
# @param body [Hash] The key value pairs to update.
|
107
|
+
# @param opts [Hash] additional options to pass to the {Parse::Client} request.
|
108
|
+
# @param headers [Hash] additional HTTP headers to send with the request.
|
109
|
+
# @return [Parse::Response]
|
73
110
|
def update_object(className, id, body = {}, headers: {}, **opts)
|
74
111
|
response = request :put, uri_path(className,id) , body: body, headers: headers, opts: opts
|
75
112
|
response.parse_class = className if response.present?
|
data/lib/parse/api/push.rb
CHANGED
@@ -4,9 +4,14 @@
|
|
4
4
|
module Parse
|
5
5
|
|
6
6
|
module API
|
7
|
-
#
|
7
|
+
# Defines the Parse Push notification service interface for the Parse REST API
|
8
8
|
module Push
|
9
9
|
PUSH_PATH = "push"
|
10
|
+
|
11
|
+
# Update the schema for a collection.
|
12
|
+
# @param payload [Hash] the paylod for the Push notification.
|
13
|
+
# @return [Parse::Response]
|
14
|
+
# @see https://parseplatform.github.io/docs/rest/guide/#sending-pushes Sending Pushes
|
10
15
|
def push(payload = {})
|
11
16
|
request :post, PUSH_PATH, body: payload.as_json
|
12
17
|
end
|
data/lib/parse/api/schemas.rb
CHANGED
@@ -4,17 +4,31 @@
|
|
4
4
|
module Parse
|
5
5
|
|
6
6
|
module API
|
7
|
-
#
|
7
|
+
# Defines the Schema interface for the Parse REST API
|
8
8
|
module Schema
|
9
9
|
SCHEMAS_PATH = "schemas"
|
10
|
+
|
11
|
+
# Get the schema for a collection.
|
12
|
+
# @param className [String] the name of the remote Parse collection.
|
13
|
+
# @return [Parse::Response]
|
10
14
|
def schema(className)
|
11
15
|
request :get, "#{SCHEMAS_PATH}/#{className}"
|
12
16
|
end
|
13
17
|
|
18
|
+
# Create a new collection with the specific schema.
|
19
|
+
# @param className [String] the name of the remote Parse collection.
|
20
|
+
# @param schema [Hash] the schema hash. This is a specific format specified by
|
21
|
+
# Parse.
|
22
|
+
# @return [Parse::Response]
|
14
23
|
def create_schema(className, schema)
|
15
24
|
request :post, "#{SCHEMAS_PATH}/#{className}", body: schema
|
16
25
|
end
|
17
26
|
|
27
|
+
# Update the schema for a collection.
|
28
|
+
# @param className [String] the name of the remote Parse collection.
|
29
|
+
# @param schema [Hash] the schema hash. This is a specific format specified by
|
30
|
+
# Parse.
|
31
|
+
# @return [Parse::Response]
|
18
32
|
def update_schema(className, schema)
|
19
33
|
request :put, "#{SCHEMAS_PATH}/#{className}", body: schema
|
20
34
|
end
|
data/lib/parse/api/sessions.rb
CHANGED
@@ -4,9 +4,14 @@
|
|
4
4
|
module Parse
|
5
5
|
|
6
6
|
module API
|
7
|
+
# Defines the Session class interface for the Parse REST API
|
7
8
|
module Sessions
|
8
9
|
SESSION_PATH_PREFIX = "sessions"
|
9
10
|
|
11
|
+
# Fetch a session record for a given session token.
|
12
|
+
# @param session_token [String] an active session token.
|
13
|
+
# @param opts [Hash] additional options to pass to the {Parse::Client} request.
|
14
|
+
# @return [Parse::Response]
|
10
15
|
def fetch_session(session_token, **opts)
|
11
16
|
opts.merge!({use_master_key: false, cache: false})
|
12
17
|
headers = {Parse::Protocol::SESSION_TOKEN => session_token}
|
data/lib/parse/api/users.rb
CHANGED
@@ -6,24 +6,38 @@ require 'open-uri'
|
|
6
6
|
module Parse
|
7
7
|
|
8
8
|
module API
|
9
|
+
# Defines the User class interface for the Parse REST API
|
9
10
|
module Users
|
10
|
-
|
11
|
-
# detect class names to proper URI handlers
|
11
|
+
|
12
12
|
USER_PATH_PREFIX = "users"
|
13
13
|
LOGOUT_PATH = "logout"
|
14
14
|
LOGIN_PATH = "login"
|
15
15
|
REQUEST_PASSWORD_RESET = "requestPasswordReset"
|
16
16
|
|
17
|
+
# Fetch a {Parse::User} for a given objectId.
|
18
|
+
# @param id [String] the user objectid
|
19
|
+
# @param opts [Hash] additional options to pass to the {Parse::Client} request.
|
20
|
+
# @param headers [Hash] additional HTTP headers to send with the request.
|
21
|
+
# @return [Parse::Response]
|
17
22
|
def fetch_user(id, headers: {}, **opts)
|
18
23
|
request :get, "#{USER_PATH_PREFIX}/#{id}", headers: headers, opts: opts
|
19
24
|
end
|
20
25
|
|
26
|
+
# Find users matching a set of constraints.
|
27
|
+
# @param query [Hash] query parameters.
|
28
|
+
# @param opts [Hash] additional options to pass to the {Parse::Client} request.
|
29
|
+
# @param headers [Hash] additional HTTP headers to send with the request.
|
30
|
+
# @return [Parse::Response]
|
21
31
|
def find_users(query = {}, headers: {}, **opts)
|
22
32
|
response = request :get, USER_PATH_PREFIX, query: query, headers: headers, opts: opts
|
23
33
|
response.parse_class = Parse::Model::CLASS_USER
|
24
34
|
response
|
25
35
|
end
|
26
36
|
|
37
|
+
# Find user matching this active session token.
|
38
|
+
# @param opts [Hash] additional options to pass to the {Parse::Client} request.
|
39
|
+
# @param headers [Hash] additional HTTP headers to send with the request.
|
40
|
+
# @return [Parse::Response]
|
27
41
|
def current_user(session_token, headers: {}, **opts)
|
28
42
|
headers.merge!({Parse::Protocol::SESSION_TOKEN => session_token})
|
29
43
|
response = request :get, "#{USER_PATH_PREFIX}/me", headers: headers, opts: opts
|
@@ -31,6 +45,11 @@ module Parse
|
|
31
45
|
response
|
32
46
|
end
|
33
47
|
|
48
|
+
# Create a new user.
|
49
|
+
# @param body [Hash] a hash of values related to your _User schema.
|
50
|
+
# @param opts [Hash] additional options to pass to the {Parse::Client} request.
|
51
|
+
# @param headers [Hash] additional HTTP headers to send with the request.
|
52
|
+
# @return [Parse::Response]
|
34
53
|
def create_user(body, headers: {}, **opts)
|
35
54
|
headers.merge!({ Parse::Protocol::REVOCABLE_SESSION => '1'})
|
36
55
|
if opts[:session_token].present?
|
@@ -41,27 +60,56 @@ module Parse
|
|
41
60
|
response
|
42
61
|
end
|
43
62
|
|
63
|
+
# Update a {Parse::User} record given an objectId.
|
64
|
+
# @param id [String] the Parse user objectId.
|
65
|
+
# @param body [Hash] the body of the API request.
|
66
|
+
# @param opts [Hash] additional options to pass to the {Parse::Client} request.
|
67
|
+
# @param headers [Hash] additional HTTP headers to send with the request.
|
68
|
+
# @return [Parse::Response]
|
44
69
|
def update_user(id, body = {}, headers: {}, **opts)
|
45
70
|
response = request :put, "#{USER_PATH_PREFIX}/#{id}", body: body, opts: opts
|
46
71
|
response.parse_class = Parse::Model::CLASS_USER
|
47
72
|
response
|
48
73
|
end
|
49
74
|
|
50
|
-
#
|
75
|
+
# Set the authentication service OAUth data for a user. Deleting or unlinking
|
76
|
+
# is done by setting the authData of the service name to nil.
|
77
|
+
# @param id [String] the Parse user objectId.
|
78
|
+
# @param service_name [Symbol] the name of the OAuth service.
|
79
|
+
# @param auth_data [Hash] the hash data related to the third-party service.
|
80
|
+
# @param opts [Hash] additional options to pass to the {Parse::Client} request.
|
81
|
+
# @param headers [Hash] additional HTTP headers to send with the request.
|
82
|
+
# @return [Parse::Response]
|
51
83
|
def set_service_auth_data(id, service_name, auth_data, headers: {}, **opts)
|
52
84
|
body = { authData: { service_name => auth_data } }
|
53
85
|
update_user(id, body, opts)
|
54
86
|
end
|
55
87
|
|
88
|
+
# Delete a {Parse::User} record given an objectId.
|
89
|
+
# @param id [String] the Parse user objectId.
|
90
|
+
# @param opts [Hash] additional options to pass to the {Parse::Client} request.
|
91
|
+
# @param headers [Hash] additional HTTP headers to send with the request.
|
92
|
+
# @return [Parse::Response]
|
56
93
|
def delete_user(id, headers: {}, **opts)
|
57
94
|
request :delete, "#{USER_PATH_PREFIX}/#{id}", headers: headers, opts: opts
|
58
95
|
end
|
59
96
|
|
60
|
-
|
97
|
+
# Request a password reset for a registered email.
|
98
|
+
# @param email [String] the Parse user email.
|
99
|
+
# @param opts [Hash] additional options to pass to the {Parse::Client} request.
|
100
|
+
# @param headers [Hash] additional HTTP headers to send with the request.
|
101
|
+
# @return [Parse::Response]
|
102
|
+
def request_password_reset(email, headers: {}, **opts)
|
61
103
|
body = {email: email}
|
62
|
-
request :post, REQUEST_PASSWORD_RESET, body: body, opts: opts
|
104
|
+
request :post, REQUEST_PASSWORD_RESET, body: body, opts: opts, headers: headers
|
63
105
|
end
|
64
106
|
|
107
|
+
# Login a user.
|
108
|
+
# @param username [String] the Parse user username.
|
109
|
+
# @param password [String] the Parse user's associated password.
|
110
|
+
# @param headers [Hash] additional HTTP headers to send with the request.
|
111
|
+
# @param opts [Hash] additional options to pass to the {Parse::Client} request.
|
112
|
+
# @return [Parse::Response]
|
65
113
|
def login(username, password, headers: {}, **opts)
|
66
114
|
# Probably pass Installation-ID as header
|
67
115
|
query = { username: username, password: password }
|
@@ -72,6 +120,11 @@ module Parse
|
|
72
120
|
response
|
73
121
|
end
|
74
122
|
|
123
|
+
# Logout a user by deleting the associated session.
|
124
|
+
# @param session_token [String] the Parse user session token to delete.
|
125
|
+
# @param headers [Hash] additional HTTP headers to send with the request.
|
126
|
+
# @param opts [Hash] additional options to pass to the {Parse::Client} request.
|
127
|
+
# @return [Parse::Response]
|
75
128
|
def logout(session_token, headers: {}, **opts)
|
76
129
|
headers.merge!({ Parse::Protocol::SESSION_TOKEN => session_token})
|
77
130
|
opts.merge!({use_master_key: false, session_token: session_token})
|
@@ -79,6 +132,12 @@ module Parse
|
|
79
132
|
end
|
80
133
|
|
81
134
|
# Signup a user given a username, password and, optionally, their email.
|
135
|
+
# @param username [String] the Parse user username.
|
136
|
+
# @param password [String] the Parse user's associated password.
|
137
|
+
# @param email [String] the desired Parse user's email.
|
138
|
+
# @param body [Hash] additional property values to pass when creating the user record.
|
139
|
+
# @param opts [Hash] additional options to pass to the {Parse::Client} request.
|
140
|
+
# @return [Parse::Response]
|
82
141
|
def signup(username, password, email = nil, body: {}, **opts)
|
83
142
|
body = body.merge({ username: username, password: password })
|
84
143
|
body[:email] = email || body[:email]
|
@@ -7,22 +7,37 @@ require 'active_support'
|
|
7
7
|
require 'active_support/core_ext'
|
8
8
|
|
9
9
|
require_relative 'protocol'
|
10
|
-
|
11
|
-
# This middleware takes all outgoing requests and adds the proper header values
|
12
|
-
# base on the client configuration.
|
10
|
+
|
13
11
|
module Parse
|
14
12
|
|
15
13
|
module Middleware
|
16
|
-
|
14
|
+
# This middleware handles sending the proper authentication headers to the
|
15
|
+
# Parse REST API endpoint.
|
17
16
|
class Authentication < Faraday::Middleware
|
18
17
|
include Parse::Protocol
|
19
|
-
DISABLE_MASTER_KEY = "X-Disable-Parse-Master-Key"
|
18
|
+
DISABLE_MASTER_KEY = "X-Disable-Parse-Master-Key".freeze
|
19
|
+
# @return [String] the application id for this Parse endpoint.
|
20
20
|
attr_accessor :application_id
|
21
|
+
# @return [String] the REST API Key for this Parse endpoint.
|
21
22
|
attr_accessor :api_key
|
23
|
+
# The Master key API Key for this Parse endpoint. This is optional. If
|
24
|
+
# provided, it will be sent in every request.
|
25
|
+
# @return [String]
|
22
26
|
attr_accessor :master_key
|
23
|
-
|
24
|
-
|
25
|
-
|
27
|
+
|
28
|
+
#
|
29
|
+
# @param adapter [Faraday::Adapter] An instance of the Faraday adapter
|
30
|
+
# used for the connection. Defaults Faraday::Adapter::NetHttp.
|
31
|
+
# @param options [Hash] the options containing Parse authentication data.
|
32
|
+
# @option options [String] :application_id the application id.
|
33
|
+
# @option options [String] :api_key the REST API key.
|
34
|
+
# @option options [String] :master_key the Master Key for this application.
|
35
|
+
# If it is set, it will be sent on every request unless this middleware sees
|
36
|
+
# {DISABLE_MASTER_KEY} as an entry in the headers section.
|
37
|
+
# @option options [String] :content_type the content type format header. Defaults to
|
38
|
+
# {Parse::Protocol::CONTENT_TYPE_FORMAT}.
|
39
|
+
def initialize(adapter, options = {})
|
40
|
+
super(adapter)
|
26
41
|
@application_id = options[:application_id]
|
27
42
|
@api_key = options[:api_key]
|
28
43
|
@master_key = options[:master_key]
|
@@ -30,10 +45,12 @@ module Parse
|
|
30
45
|
end
|
31
46
|
|
32
47
|
# we dup the call for thread-safety
|
48
|
+
# @!visibility private
|
33
49
|
def call(env)
|
34
50
|
dup.call!(env)
|
35
51
|
end
|
36
52
|
|
53
|
+
# @!visibility private
|
37
54
|
def call!(env)
|
38
55
|
# We add the main Parse protocol headers
|
39
56
|
headers = {}
|
@@ -0,0 +1,206 @@
|
|
1
|
+
|
2
|
+
require_relative 'request'
|
3
|
+
require_relative 'response'
|
4
|
+
|
5
|
+
|
6
|
+
module Parse
|
7
|
+
# Create a new batch operation.
|
8
|
+
# @param reqs [Array<Parse::Request>] a set of requests to batch.
|
9
|
+
# @return [BatchOperation] a new {BatchOperation} with the given change requests.
|
10
|
+
def self.batch(reqs = nil)
|
11
|
+
BatchOperation.new(reqs)
|
12
|
+
end
|
13
|
+
|
14
|
+
# This class provides a standard way to submit, manage and process batch operations
|
15
|
+
# for Parse::Objects and associations.
|
16
|
+
#
|
17
|
+
# Batch requests are supported implicitly and intelligently through an
|
18
|
+
# extension of array. When an array of Parse::Object subclasses is saved,
|
19
|
+
# Parse-Stack will batch all possible save operations for the objects in the
|
20
|
+
# array that have changed. It will also batch save 50 at a time until all items
|
21
|
+
# in the array are saved. Note: Parse does not allow batch saving Parse::User objects.
|
22
|
+
#
|
23
|
+
# songs = Songs.first 1000 #first 1000 songs
|
24
|
+
# songs.each do |song|
|
25
|
+
# # ... modify song ...
|
26
|
+
# end
|
27
|
+
#
|
28
|
+
# # will batch save 50 items at a time until all are saved.
|
29
|
+
# songs.save
|
30
|
+
#
|
31
|
+
# The objects do not have to be of the same collection in order to be supported in the
|
32
|
+
# batch request.
|
33
|
+
# @see Array.save
|
34
|
+
# @see Array.destroy
|
35
|
+
class BatchOperation
|
36
|
+
|
37
|
+
attr_accessor :requests, :responses
|
38
|
+
include Enumerable
|
39
|
+
|
40
|
+
# @return [Parse::Client] the client to be used for the request.
|
41
|
+
def client
|
42
|
+
@client ||= Parse::Client.client
|
43
|
+
end
|
44
|
+
|
45
|
+
# @param reqs [Array<Parse::Request>] an array of requests.
|
46
|
+
def initialize(reqs = nil)
|
47
|
+
@requests = []
|
48
|
+
@responses = []
|
49
|
+
reqs = [reqs] unless reqs.is_a?(Enumerable)
|
50
|
+
reqs.each { |r| add(r) } if reqs.is_a?(Enumerable)
|
51
|
+
end
|
52
|
+
|
53
|
+
# Add an additional request to this batch.
|
54
|
+
# @overload add(req)
|
55
|
+
# @param req [Parse::Request] the request to append.
|
56
|
+
# @return [Array<Parse::Request>] the set of requests.
|
57
|
+
# @overload add(batch)
|
58
|
+
# @param req [Parse::BatchOperation] add all the requests from this batch operation.
|
59
|
+
# @return [Array<Parse::Request>] the set of requests.
|
60
|
+
def add(req)
|
61
|
+
if req.respond_to?(:change_requests)
|
62
|
+
requests = req.change_requests.select { |r| r.is_a?(Parse::Request) }
|
63
|
+
@requests += requests
|
64
|
+
elsif req.is_a?(Array)
|
65
|
+
requests = req.select { |r| r.is_a?(Parse::Request) }
|
66
|
+
@requests += requests
|
67
|
+
elsif req.is_a?(BatchOperation)
|
68
|
+
@requests += req.requests if req.is_a?(BatchOperation)
|
69
|
+
else
|
70
|
+
@requests.push(req) if req.is_a?(Parse::Request)
|
71
|
+
end
|
72
|
+
@requests
|
73
|
+
end
|
74
|
+
|
75
|
+
# This method is for interoperability with Parse::Object instances.
|
76
|
+
# @see Parse::Object#change_requests
|
77
|
+
def change_requests
|
78
|
+
@requests
|
79
|
+
end
|
80
|
+
|
81
|
+
# @return [Array]
|
82
|
+
def each
|
83
|
+
return enum_for(:each) unless block_given?
|
84
|
+
@requests.each(&Proc.new)
|
85
|
+
end
|
86
|
+
|
87
|
+
# @return [Hash] a formatted payload for the batch request.
|
88
|
+
def as_json(*args)
|
89
|
+
{ requests: requests }.as_json
|
90
|
+
end
|
91
|
+
|
92
|
+
# @return [Integer] the number of requests in the batch.
|
93
|
+
def count
|
94
|
+
@requests.count
|
95
|
+
end
|
96
|
+
|
97
|
+
# Remove all requests in this batch.
|
98
|
+
# @return [Array]
|
99
|
+
def clear!
|
100
|
+
@requests.clear
|
101
|
+
end
|
102
|
+
|
103
|
+
# @return [Boolean] true if the request was successful.
|
104
|
+
def success?
|
105
|
+
return false if @responses.empty?
|
106
|
+
@responses.compact.all?(&:success?)
|
107
|
+
end
|
108
|
+
|
109
|
+
# @return [Boolean] true if the request had an error.
|
110
|
+
def error?
|
111
|
+
return false if @responses.empty?
|
112
|
+
! success?
|
113
|
+
end
|
114
|
+
|
115
|
+
# Submit the batch operation in chunks until they are all complete. In general,
|
116
|
+
# Parse limits requests in each batch to 50 and it is possible that a {BatchOperation}
|
117
|
+
# instance contains more than 50 requests. This method will slice up the array of
|
118
|
+
# request and send them based on the `segment` amount until they have all been submitted.
|
119
|
+
# @param segment [Integer] the number of requests to send in each batch. Default 50.
|
120
|
+
# @return [Array<Parse::Response>] the corresponding set of responses for
|
121
|
+
# each request in the batch.
|
122
|
+
def submit(segment = 50)
|
123
|
+
@responses = []
|
124
|
+
@requests.uniq!(&:signature)
|
125
|
+
@requests.each_slice(segment) do |slice|
|
126
|
+
@responses << client.batch_request( BatchOperation.new(slice) )
|
127
|
+
#throttle
|
128
|
+
# sleep (slice.count.to_f / MAX_REQ_SEC.to_f )
|
129
|
+
end
|
130
|
+
@responses.flatten!
|
131
|
+
#puts "Requests: #{@requests.count} == Response: #{@responses.count}"
|
132
|
+
@requests.zip(@responses).each(&Proc.new) if block_given?
|
133
|
+
@responses
|
134
|
+
end
|
135
|
+
alias_method :save, :submit
|
136
|
+
|
137
|
+
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
141
|
+
class Array
|
142
|
+
|
143
|
+
# Submit a batch request for deleting a set of Parse::Objects.
|
144
|
+
# @example
|
145
|
+
# # assume Post and Author are Parse models
|
146
|
+
# author = Author.first
|
147
|
+
# posts = Post.all author: author
|
148
|
+
# posts.destroy # batch destroy request
|
149
|
+
# @return [Parse::BatchOperation] the batch operation performed.
|
150
|
+
# @see Parse::BatchOperation
|
151
|
+
def destroy
|
152
|
+
batch = Parse::BatchOperation.new
|
153
|
+
each do |o|
|
154
|
+
next unless o.respond_to?(:destroy_request)
|
155
|
+
r = o.destroy_request
|
156
|
+
batch.add(r) unless r.nil?
|
157
|
+
end
|
158
|
+
batch.submit
|
159
|
+
batch
|
160
|
+
end
|
161
|
+
|
162
|
+
# Submit a batch request for deleting a set of Parse::Objects.
|
163
|
+
# Batch requests are supported implicitly and intelligently through an
|
164
|
+
# extension of array. When an array of Parse::Object subclasses is saved,
|
165
|
+
# Parse-Stack will batch all possible save operations for the objects in the
|
166
|
+
# array that have changed. It will also batch save 50 at a time until all items
|
167
|
+
# in the array are saved. Note: Parse does not allow batch saving Parse::User objects.
|
168
|
+
# @note The objects of the array to be saved do not all have to be of the same collection.
|
169
|
+
# @param merge [Boolean] whether to merge the updated changes to the series of
|
170
|
+
# objects back to the original ones submitted. If you don't need the original objects
|
171
|
+
# to be updated with the changes, set this to false for improved performance.
|
172
|
+
# @param force [Boolean] Do not skip objects that do not have pending changes (dirty tracking).
|
173
|
+
# @example
|
174
|
+
# # assume Post and Author are Parse models
|
175
|
+
# author = Author.first
|
176
|
+
# posts = Post.first 100
|
177
|
+
# posts.each { |post| post.author = author }
|
178
|
+
# posts.save # batch save
|
179
|
+
# @return [Parse::BatchOperation] the batch operation performed.
|
180
|
+
# @see Parse::BatchOperation
|
181
|
+
def save(merge: true, force: false)
|
182
|
+
batch = Parse::BatchOperation.new
|
183
|
+
objects = {}
|
184
|
+
each do |o|
|
185
|
+
next unless o.is_a?(Parse::Object)
|
186
|
+
objects[o.object_id] = o
|
187
|
+
batch.add o.change_requests(force)
|
188
|
+
end
|
189
|
+
if merge == false
|
190
|
+
batch.submit
|
191
|
+
return batch
|
192
|
+
end
|
193
|
+
#rebind updates
|
194
|
+
batch.submit do |request, response|
|
195
|
+
next unless request.tag.present? && response.present? && response.success?
|
196
|
+
o = objects[request.tag]
|
197
|
+
next unless o.is_a?(Parse::Object)
|
198
|
+
result = response.result
|
199
|
+
o.id = result['objectId'] if o.id.blank?
|
200
|
+
o.set_attributes!(result)
|
201
|
+
o.clear_changes!
|
202
|
+
end
|
203
|
+
batch
|
204
|
+
end #save!
|
205
|
+
|
206
|
+
end
|