parse-stack 1.5.2 → 1.5.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (52) hide show
  1. checksums.yaml +4 -4
  2. data/Changes.md +5 -0
  3. data/Gemfile.lock +1 -1
  4. data/README.md +40 -80
  5. data/lib/parse/api/all.rb +7 -0
  6. data/lib/parse/api/analytics.rb +8 -3
  7. data/lib/parse/api/apps.rb +29 -1
  8. data/lib/parse/api/batch.rb +14 -129
  9. data/lib/parse/api/cloud_functions.rb +9 -0
  10. data/lib/parse/api/config.rb +10 -1
  11. data/lib/parse/api/files.rb +7 -2
  12. data/lib/parse/api/hooks.rb +45 -2
  13. data/lib/parse/api/objects.rb +43 -6
  14. data/lib/parse/api/push.rb +6 -1
  15. data/lib/parse/api/schemas.rb +15 -1
  16. data/lib/parse/api/sessions.rb +5 -0
  17. data/lib/parse/api/users.rb +64 -5
  18. data/lib/parse/client/authentication.rb +25 -8
  19. data/lib/parse/client/batch.rb +206 -0
  20. data/lib/parse/client/body_builder.rb +12 -6
  21. data/lib/parse/client/caching.rb +42 -10
  22. data/lib/parse/client/protocol.rb +51 -46
  23. data/lib/parse/client/response.rb +1 -47
  24. data/lib/parse/client.rb +171 -42
  25. data/lib/parse/model/acl.rb +184 -39
  26. data/lib/parse/model/associations/belongs_to.rb +1 -0
  27. data/lib/parse/model/classes/role.rb +7 -1
  28. data/lib/parse/model/classes/session.rb +7 -3
  29. data/lib/parse/model/classes/user.rb +107 -0
  30. data/lib/parse/model/core/actions.rb +166 -115
  31. data/lib/parse/model/core/fetching.rb +105 -0
  32. data/lib/parse/model/core/properties.rb +40 -13
  33. data/lib/parse/model/core/querying.rb +123 -39
  34. data/lib/parse/model/core/schema.rb +22 -32
  35. data/lib/parse/model/object.rb +26 -20
  36. data/lib/parse/model/pointer.rb +1 -0
  37. data/lib/parse/query/constraint.rb +65 -27
  38. data/lib/parse/query/constraints.rb +0 -3
  39. data/lib/parse/query/operation.rb +33 -22
  40. data/lib/parse/query/ordering.rb +10 -5
  41. data/lib/parse/stack/generators/rails.rb +5 -1
  42. data/lib/parse/stack/generators/templates/model_installation.rb +1 -1
  43. data/lib/parse/stack/generators/templates/model_role.rb +1 -1
  44. data/lib/parse/stack/generators/templates/model_session.rb +2 -2
  45. data/lib/parse/stack/generators/templates/model_user.rb +1 -1
  46. data/lib/parse/stack/generators/templates/parse.rb +0 -1
  47. data/lib/parse/stack/railtie.rb +1 -0
  48. data/lib/parse/stack/tasks.rb +3 -1
  49. data/lib/parse/stack/version.rb +3 -1
  50. data/lib/parse/webhooks/registration.rb +3 -3
  51. data/lib/parse/webhooks.rb +88 -7
  52. metadata +5 -3
@@ -4,59 +4,70 @@
4
4
  require 'active_support'
5
5
  require 'active_support/inflector'
6
6
 
7
- # The base operation class used in generating queries.
8
- # An Operation contains an operand (field) and the
9
- # operator (ex. equals, greater than, etc)
10
- # Each unique operation type needs a handler that is responsible
11
- # for creating a Constraint with a given value.
12
- # When creating a new operation, you need to register the operation
13
- # method and the class that will be the handler.
7
+
14
8
  module Parse
9
+
10
+ # An operation is the core part of {Parse::Constraint} when performing
11
+ # queries. It contains an operand (the Parse field) and an operator (the Parse
12
+ # operation). These combined with a value, provide you with a constraint.
13
+ #
14
+ # All operation registrations add methods to the Symbol class.
15
15
  class Operation
16
- attr_accessor :operand, :operator
16
+
17
+ # @!attribute operand
18
+ # The field in Parse for this operation.
19
+ # @return [Symbol]
20
+ attr_accessor :operand
21
+
22
+ # @!attribute operator
23
+ # The type of Parse operation.
24
+ # @return [Symbol]
25
+ attr_accessor :operator
26
+
17
27
  class << self
28
+ # @return [Hash] a hash containing all supported Parse operations mapped
29
+ # to their {Parse::Constraint} subclass.
18
30
  attr_accessor :operators
31
+
19
32
  def operators
20
33
  @operators ||= {}
21
34
  end
22
35
  end
23
- # a valid Operation has a handler, operand and operator.
36
+
37
+ # Whether this operation is defined properly.
24
38
  def valid?
25
39
  ! (@operand.nil? || @operator.nil? || handler.nil?)
26
40
  end
27
41
 
28
- # returns the constraint class designed to handle this operator
42
+ # @return [Parse::Constraint] the constraint class designed to handle
43
+ # this operator.
29
44
  def handler
30
45
  Operation.operators[@operator] unless @operator.nil?
31
46
  end
32
47
 
48
+ # Create a new operation.
49
+ # @param field [Symbol] the name of the Parse field
50
+ # @param op [Symbol] the operator name (ex. :eq, :lt)
33
51
  def initialize(field, op)
34
52
  self.operand = field.to_sym
35
53
  self.operand = :objectId if operand == :id
36
54
  self.operator = op.to_sym
37
55
  end
38
56
 
57
+ # @!visibility private
39
58
  def inspect
40
59
  "#{operator.inspect}(#{operand.inspect})"
41
60
  end
42
61
 
43
- # create a new constraint based on the handler that had
62
+ # Create a new constraint based on the handler that had
44
63
  # been registered with this operation.
64
+ # @param value [Object] a value to pass to the constraint subclass.
65
+ # @return [Parse::Constraint] a constraint with this operation and value.
45
66
  def constraint(value = nil)
46
67
  handler.new(self, value)
47
68
  end
48
69
 
49
- # have a way to register an operation type.
50
- # Example:
51
- # register :eq, MyEqualityHandlerClass
52
- # the above registered the equality operator which we define to be
53
- # a new method on the Symbol class ('eq'), which when passed a value
54
- # we will forward the request to the MyEqualityHandlerClass, so that
55
- # for a field called 'name', we can do
56
- #
57
- # :name.eq (returns operation)
58
- # :name.eq(value) # returns constraint provided by the handler
59
- #
70
+ # Register a new symbol operator method mapped to a specific {Parse::Constraint}.
60
71
  def self.register(op, klass)
61
72
  Operation.operators[op.to_sym] = klass
62
73
  Symbol.send :define_method, op do |value = nil|
@@ -20,12 +20,15 @@ module Parse
20
20
  class Order
21
21
  # The Parse operators to indicate ordering direction.
22
22
  ORDERING = {asc: '', desc: '-'}.freeze
23
+
23
24
  # @!attribute [rw] field
24
- # @return [Symbol] the name of the field
25
+ # @return [Symbol] the name of the field
26
+ attr_accessor :field
27
+
25
28
  # @!attribute [rw] direction
26
- # The direction of the sorting. This is either `:asc` or `:desc`.
27
- # @return [Symbol]
28
- attr_accessor :field, :direction
29
+ # The direction of the sorting. This is either `:asc` or `:desc`.
30
+ # @return [Symbol]
31
+ attr_accessor :direction
29
32
 
30
33
  def initialize(field, order = :asc)
31
34
  @field = field.to_sym || :objectId
@@ -36,16 +39,18 @@ module Parse
36
39
  @field = f.to_sym
37
40
  end
38
41
 
39
- # get the Parse keyword for ordering.
42
+ # @return [String] the sort direction
40
43
  def polarity
41
44
  ORDERING[@direction] || ORDERING[:asc]
42
45
  end # polarity
43
46
 
47
+ # @return [String] the ordering as a string
44
48
  def to_s
45
49
  "" if @field.nil?
46
50
  polarity + @field.to_s
47
51
  end
48
52
 
53
+ # @!visibility private
49
54
  def inspect
50
55
  "#{@direction.to_s}(#{@field.inspect})"
51
56
  end
@@ -6,12 +6,14 @@ require 'parse/stack/tasks'
6
6
  require 'rails/generators'
7
7
  require 'rails/generators/named_base'
8
8
 
9
+ # Module namespace to show up in the generators list for Rails.
9
10
  module ParseStack
10
-
11
+ # Adds support for rails when installing Parse::Stack to a Rails project.
11
12
  class InstallGenerator < Rails::Generators::Base
12
13
  source_root File.expand_path("../templates", __FILE__)
13
14
 
14
15
  desc "This generator creates an initializer file at config/initializers"
16
+ # @!visibility private
15
17
  def generate_initializer
16
18
  copy_file "parse.rb", "config/initializers/parse.rb"
17
19
  copy_file "model_user.rb", File.join("app/models", "user.rb")
@@ -22,12 +24,14 @@ module ParseStack
22
24
  end
23
25
  end
24
26
 
27
+ # @!visibility private
25
28
  class ModelGenerator < Rails::Generators::NamedBase
26
29
  source_root File.expand_path(__dir__ + "/templates")
27
30
  desc "Creates a Parse::Object model subclass."
28
31
  argument :attributes, type: :array, default: [], banner: "field:type field:type"
29
32
  check_class_collision
30
33
 
34
+ # @!visibility private
31
35
  def create_model_file
32
36
  @allowed_types = Parse::Properties::TYPES - [:acl, :id, :relation]
33
37
  template "model.erb", File.join("app/models", class_path, "#{file_name}.rb")
@@ -1,5 +1,5 @@
1
1
 
2
-
2
+ # The Parse _Installation collection
3
3
  class Parse::Installation < Parse::Object
4
4
  # See: https://github.com/modernistik/parse-stack#parseinstallation
5
5
  # add additional properties here
@@ -1,5 +1,5 @@
1
1
 
2
-
2
+ # The Parse _Role collection
3
3
  class Parse::Role < Parse::Object
4
4
  # See: https://github.com/modernistik/parse-stack#parserole
5
5
  # add additional properties here
@@ -1,6 +1,6 @@
1
1
 
2
-
3
- class Parse::Role < Parse::Object
2
+ # The Parse _Session collection
3
+ class Parse::Session < Parse::Object
4
4
  # See: https://github.com/modernistik/parse-stack#parsesession
5
5
  # add additional properties here
6
6
  end
@@ -1,5 +1,5 @@
1
1
 
2
- # See: https://github.com/modernistik/parse-stack#parseuser
2
+ # The Parse _User collection
3
3
  class Parse::User < Parse::Object
4
4
  # add additional properties
5
5
 
@@ -2,7 +2,6 @@ require 'parse/stack'
2
2
 
3
3
  # Set your specific Parse keys in your ENV. For all connection options, see
4
4
  # https://github.com/modernistik/parse-stack#connection-setup
5
-
6
5
  Parse.setup app_id: ENV['PARSE_APP_ID'],
7
6
  api_key: ENV['PARSE_API_KEY'],
8
7
  master_key: ENV['PARSE_MASTER_KEY'],
@@ -3,6 +3,7 @@
3
3
 
4
4
  module Parse
5
5
  module Stack
6
+ # Support for adding rake tasks to a Rails project.
6
7
  class Railtie < ::Rails::Railtie
7
8
 
8
9
  rake_tasks do
@@ -11,14 +11,16 @@ require 'rake/dsl_definition'
11
11
  module Parse
12
12
 
13
13
  module Stack
14
-
14
+ # Loads and installs all Parse::Stack related tasks in a rake file.
15
15
  def self.load_tasks
16
16
  Parse::Stack::Tasks.new.install_tasks
17
17
  end
18
18
 
19
+ # Defines all the related Rails tasks for Parse.
19
20
  class Tasks
20
21
  include Rake::DSL if defined? Rake::DSL
21
22
 
23
+ # Installs the rake tasks.
22
24
  def install_tasks
23
25
 
24
26
  if defined?(::Rails)
@@ -3,7 +3,9 @@
3
3
 
4
4
  module Parse
5
5
  # @author Anthony Persaud
6
+ # The Parse Server SDK for Ruby
6
7
  module Stack
7
- VERSION = "1.5.2"
8
+ # The current version.
9
+ VERSION = "1.5.3"
8
10
  end
9
11
  end
@@ -8,11 +8,11 @@ require 'active_support/core_ext/string'
8
8
  require 'active_support/core_ext'
9
9
 
10
10
  module Parse
11
-
11
+ # Interface to the CloudCode webhooks API.
12
12
  module Webhook
13
-
13
+ # Module to support registering Parse CloudCode webhooks.
14
14
  module Registration
15
-
15
+ # The set of allowed trigger types.
16
16
  ALLOWED_HOOKS = Parse::API::Hooks::TRIGGER_NAMES + [:function]
17
17
 
18
18
  # removes all registered webhook functions with Parse Server.
@@ -18,6 +18,18 @@ module Parse
18
18
 
19
19
  class Object
20
20
 
21
+ # Register a webhook function for this subclass.
22
+ # @example
23
+ # class Post < Parse::Object
24
+ #
25
+ # webhook_function :helloWorld do
26
+ # # ... do something when this function is called ...
27
+ # end
28
+ # end
29
+ # @param functionName [String] the literal name of the function to be registered with the server.
30
+ # @yield (see Parse::Object.webhook)
31
+ # @param block (see Parse::Object.webhook)
32
+ # @return (see Parse::Object.webhook)
21
33
  def self.webhook_function(functionName, block = nil)
22
34
  if block_given?
23
35
  Parse::Webhooks.route(:function, functionName, &Proc.new)
@@ -28,6 +40,20 @@ module Parse
28
40
  end
29
41
  end
30
42
 
43
+ # Register a webhook trigger or function for this subclass.
44
+ # @example
45
+ # class Post < Parse::Object
46
+ #
47
+ # webhook :before_save do
48
+ # # ... do something ...
49
+ # parse_object
50
+ # end
51
+ #
52
+ # end
53
+ # @param type (see Parse::Webhooks.route)
54
+ # @yield the body of the function to be evaluated in the scope of a {Parse::Payload} instance.
55
+ # @param block [Symbol] the name of the method to call, if no block is passed.
56
+ # @return (see Parse::Webhooks.route)
31
57
  def self.webhook(type, block = nil)
32
58
 
33
59
  if type == :function
@@ -50,28 +76,51 @@ module Parse
50
76
  end
51
77
 
52
78
  class Payload
79
+ # This method will intentionally raise a {WebhookErrorResponse}, which when used inside
80
+ # of a registered cloud code webhook function or trigger, will halt processing
81
+ # and return the proper error response code back to the Parse server.
82
+ # @param msg [String] the error message
83
+ # @raise WebhookErrorResponse
84
+ # @return [WebhookErrorResponse]
53
85
  def error!(msg = "")
54
86
  raise WebhookErrorResponse, msg
55
87
  end
56
88
  end
57
89
 
90
+ # The error to be raised in registered trigger or function webhook blocks that
91
+ # will trigger the Parse::Webhooks application to return the proper error response.
58
92
  class WebhookErrorResponse < StandardError; end;
93
+ # A Rack-based application middlware to handle incoming Parse cloud code webhook
94
+ # requests.
59
95
  class Webhooks
60
-
61
- def self.reload!(args = {})
62
-
63
- end
64
-
65
96
  include Client::Connectable
66
97
  extend Webhook::Registration
67
-
68
98
  HTTP_PARSE_WEBHOOK = "HTTP_X_PARSE_WEBHOOK_KEY"
69
99
  HTTP_PARSE_APPLICATION_ID = "HTTP_X_PARSE_APPLICATION_ID"
70
100
  CONTENT_TYPE = "application/json"
101
+
102
+ # @!attribute key
103
+ # The Parse Webhook Key to be used for authenticating webhook requests.
104
+ # By default this is taken from the PARSE_WEBHOOK_KEY environment variable if
105
+ # present.
106
+ # @return [String]
71
107
  attr_accessor :key
108
+
72
109
  class << self
110
+
111
+ # Allows support for web frameworks that support auto-reloading of source.
112
+ # @!visibility private
113
+ def reload!(args = {})
114
+ end
115
+
116
+ # @return [Boolean] whether to print additional logging information. You may also
117
+ # set this to `:debug` for additional verbosity.
73
118
  attr_accessor :logging
74
119
 
120
+ # A hash-like structure composing of all the registered webhook
121
+ # triggers and functions. These are `:before_save`, `:after_save`,
122
+ # `:before_delete`, `:after_delete` or `:function`.
123
+ # @return [OpenStruct]
75
124
  def routes
76
125
  @routes ||= OpenStruct.new( {
77
126
  before_save: {}, after_save: {},
@@ -79,6 +128,15 @@ module Parse
79
128
  })
80
129
  end
81
130
 
131
+ # Internally registers a route for a specific webhook trigger or function.
132
+ # @param type [Symbol] The type of cloud code webhook to register. This can be any
133
+ # of the supported routes. These are `:before_save`, `:after_save`,
134
+ # `:before_delete`, `:after_delete` or `:function`.
135
+ # @param className [String] if `type` is not `:function`, then this registers
136
+ # a trigger for the given className. Otherwise, className is treated to be the function
137
+ # name to register with Parse server.
138
+ # @yield the block that will handle of the webhook trigger or function.
139
+ # @return (see routes)
82
140
  def route(type, className, block = nil)
83
141
  type = type.to_s.underscore.to_sym #support camelcase
84
142
  if type != :function && className.respond_to?(:parse_class)
@@ -98,9 +156,12 @@ module Parse
98
156
  else
99
157
  routes[type][className] = block
100
158
  end
101
- #puts "Webhook: #{type} -> #{className}..."
159
+ @routes
102
160
  end
103
161
 
162
+ # Run a locally registered webhook function. This bypasses calling a
163
+ # function through Parse-Server if the method handler is registered locally.
164
+ # @return [Object] the result of the function.
104
165
  def run_function(name, params)
105
166
  payload = Payload.new
106
167
  payload.function_name = name
@@ -108,6 +169,12 @@ module Parse
108
169
  call_route(:function, name, payload)
109
170
  end
110
171
 
172
+ # Calls the set of registered webhook trigger blocks or the specific function block.
173
+ # This method is usually called when an incoming request from Parse Server is received.
174
+ # @param type (see route)
175
+ # @param className (see route)
176
+ # @param payload [Parse::Payload] the payload object received from the server.
177
+ # @return [Object] the result of the trigger or function.
111
178
  def call_route(type, className, payload = nil)
112
179
  type = type.to_s.underscore.to_sym #support camelcase
113
180
  className = className.parse_class if className.respond_to?(:parse_class)
@@ -138,10 +205,16 @@ module Parse
138
205
  result
139
206
  end
140
207
 
208
+ # Generates a success response for Parse Server.
209
+ # @param data [Object] the data to send back with the success.
210
+ # @return [Hash] a success data payload
141
211
  def success(data = true)
142
212
  { success: data }.to_json
143
213
  end
144
214
 
215
+ # Generates an error response for Parse Server.
216
+ # @param data [Object] the data to send back with the error.
217
+ # @return [Hash] a error data payload
145
218
  def error(data = false)
146
219
  { error: data }.to_json
147
220
  end
@@ -150,6 +223,14 @@ module Parse
150
223
  @key ||= ENV['PARSE_WEBHOOK_KEY']
151
224
  end
152
225
 
226
+ # Standard Rack call method. This method processes an incoming cloud code
227
+ # webhook request from Parse Server, validates it and executes any registered handlers for it.
228
+ # The result of the handler for the matching webhook request is sent back to
229
+ # Parse Server. If the handler raises a {Parse::WebhookErrorResponse},
230
+ # it will return the proper error response.
231
+ # @param env [Hash] the environment hash in a Rack request.
232
+ # @return [Object] the value of calling `finish` on the Rack::Response object.
233
+ # @todo Create a call! method that takes a dup of this env.
153
234
  def call(env)
154
235
 
155
236
  request = Rack::Request.new env
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.5.2
4
+ version: 1.5.3
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-10-27 00:00:00.000000000 Z
11
+ date: 2016-10-31 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activemodel
@@ -199,6 +199,7 @@ files:
199
199
  - lib/parse/api/users.rb
200
200
  - lib/parse/client.rb
201
201
  - lib/parse/client/authentication.rb
202
+ - lib/parse/client/batch.rb
202
203
  - lib/parse/client/body_builder.rb
203
204
  - lib/parse/client/caching.rb
204
205
  - lib/parse/client/protocol.rb
@@ -217,6 +218,7 @@ files:
217
218
  - lib/parse/model/classes/session.rb
218
219
  - lib/parse/model/classes/user.rb
219
220
  - lib/parse/model/core/actions.rb
221
+ - lib/parse/model/core/fetching.rb
220
222
  - lib/parse/model/core/properties.rb
221
223
  - lib/parse/model/core/querying.rb
222
224
  - lib/parse/model/core/schema.rb
@@ -275,7 +277,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
275
277
  version: '0'
276
278
  requirements: []
277
279
  rubyforge_project:
278
- rubygems_version: 2.6.6
280
+ rubygems_version: 2.5.1
279
281
  signing_key:
280
282
  specification_version: 4
281
283
  summary: Parse-Server Ruby Client and Relational Mapper