moonrope 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/Rakefile +5 -0
- data/lib/moonrope.rb +37 -0
- data/lib/moonrope/action.rb +163 -0
- data/lib/moonrope/action_result.rb +63 -0
- data/lib/moonrope/base.rb +130 -0
- data/lib/moonrope/before_action.rb +24 -0
- data/lib/moonrope/controller.rb +49 -0
- data/lib/moonrope/dsl/action_dsl.rb +70 -0
- data/lib/moonrope/dsl/base_dsl.rb +74 -0
- data/lib/moonrope/dsl/controller_dsl.rb +57 -0
- data/lib/moonrope/dsl/structure_dsl.rb +63 -0
- data/lib/moonrope/dsl/structure_restriction_dsl.rb +27 -0
- data/lib/moonrope/errors.rb +48 -0
- data/lib/moonrope/eval_environment.rb +141 -0
- data/lib/moonrope/eval_helpers.rb +35 -0
- data/lib/moonrope/helper.rb +28 -0
- data/lib/moonrope/param_set.rb +44 -0
- data/lib/moonrope/rack_middleware.rb +73 -0
- data/lib/moonrope/railtie.rb +30 -0
- data/lib/moonrope/request.rb +165 -0
- data/lib/moonrope/structure.rb +83 -0
- data/lib/moonrope/version.rb +3 -0
- metadata +152 -0
@@ -0,0 +1,70 @@
|
|
1
|
+
module Moonrope
|
2
|
+
module DSL
|
3
|
+
class ActionDSL
|
4
|
+
|
5
|
+
#
|
6
|
+
# Initialize a new ActionDSL
|
7
|
+
#
|
8
|
+
# @param action [Moonrope::Action]
|
9
|
+
#
|
10
|
+
def initialize(action)
|
11
|
+
@action = action
|
12
|
+
end
|
13
|
+
|
14
|
+
#
|
15
|
+
# Set the description for the action
|
16
|
+
#
|
17
|
+
# description "Returns all users which are configured"
|
18
|
+
#
|
19
|
+
# @param value [String]
|
20
|
+
# @return [void]
|
21
|
+
#
|
22
|
+
def description(value)
|
23
|
+
@action.description = value
|
24
|
+
end
|
25
|
+
|
26
|
+
#
|
27
|
+
# Add a new param to the action's param set.
|
28
|
+
#
|
29
|
+
# param :page, "The page number", :default => 2
|
30
|
+
#
|
31
|
+
# @param name [Symbol] the name of the param
|
32
|
+
# @param description [String] a description of the action
|
33
|
+
# @param options [Hash] a hash of additional options
|
34
|
+
# @return [void]
|
35
|
+
#
|
36
|
+
def param(name, description, options = {})
|
37
|
+
@action.params[name] = options.merge(:description => description)
|
38
|
+
end
|
39
|
+
|
40
|
+
#
|
41
|
+
# Set the access condition for the action.
|
42
|
+
#
|
43
|
+
# access do
|
44
|
+
# auth.is_a?(User)
|
45
|
+
# end
|
46
|
+
#
|
47
|
+
# @yield the contents of the yield will be saved as the access condition
|
48
|
+
# @return [void]
|
49
|
+
#
|
50
|
+
def access(value = nil, &block)
|
51
|
+
@action.access = block_given? ? block : value
|
52
|
+
end
|
53
|
+
|
54
|
+
#
|
55
|
+
# Set the action to execute when this action is invoked.
|
56
|
+
#
|
57
|
+
# action do
|
58
|
+
# # Do something here and return a JSON-able value
|
59
|
+
# end
|
60
|
+
#
|
61
|
+
# @yield the contents of the yield will be saved as the action
|
62
|
+
# @return [void]
|
63
|
+
#
|
64
|
+
def action(&block)
|
65
|
+
@action.action = block
|
66
|
+
end
|
67
|
+
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
@@ -0,0 +1,74 @@
|
|
1
|
+
module Moonrope
|
2
|
+
module DSL
|
3
|
+
class BaseDSL
|
4
|
+
|
5
|
+
#
|
6
|
+
# Initiaize a new BaseDSL
|
7
|
+
#
|
8
|
+
# @param base [Moonrope::Base]
|
9
|
+
#
|
10
|
+
def initialize(base)
|
11
|
+
@base = base
|
12
|
+
end
|
13
|
+
|
14
|
+
#
|
15
|
+
# Define a new structure
|
16
|
+
#
|
17
|
+
# @param name [Symbol] the name of the structure
|
18
|
+
# @yield instance evals the block within the StructureDSL
|
19
|
+
#
|
20
|
+
def structure(name, &block)
|
21
|
+
structure = Moonrope::Structure.new(@base, name)
|
22
|
+
structure.dsl.instance_eval(&block) if block_given?
|
23
|
+
@base.structures << structure
|
24
|
+
end
|
25
|
+
|
26
|
+
#
|
27
|
+
# Define a new controller or append values to an existing
|
28
|
+
# controller if it has already been defined.
|
29
|
+
#
|
30
|
+
# @param name [Symbol] the name of the controller
|
31
|
+
# @yield instance evals the block within the ControllerDSL
|
32
|
+
#
|
33
|
+
def controller(name, &block)
|
34
|
+
existing = @base.controllers.select { |a| a.name == name }.first
|
35
|
+
if existing
|
36
|
+
controller = existing
|
37
|
+
else
|
38
|
+
controller = Moonrope::Controller.new(@base, name)
|
39
|
+
end
|
40
|
+
controller.dsl.instance_eval(&block) if block_given?
|
41
|
+
@base.controllers << controller
|
42
|
+
end
|
43
|
+
|
44
|
+
#
|
45
|
+
# Set the authenticator for the API.
|
46
|
+
#
|
47
|
+
# @yield stores the block as the authenticator
|
48
|
+
#
|
49
|
+
def authenticator(&block)
|
50
|
+
@base.authenticator = block
|
51
|
+
end
|
52
|
+
|
53
|
+
#
|
54
|
+
# Set the default access check block.
|
55
|
+
#
|
56
|
+
# @yield stores the block as the access check
|
57
|
+
#
|
58
|
+
def default_access(&block)
|
59
|
+
@base.default_access = block
|
60
|
+
end
|
61
|
+
|
62
|
+
#
|
63
|
+
# Define a new helper in the global namespace
|
64
|
+
#
|
65
|
+
# @param name [Symbol] the name of the helper
|
66
|
+
# @yield stores the block to execute for the helper
|
67
|
+
#
|
68
|
+
def helper(name, &block)
|
69
|
+
@base.helpers << Moonrope::Helper.new(name, nil, &block)
|
70
|
+
end
|
71
|
+
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
module Moonrope
|
2
|
+
module DSL
|
3
|
+
class ControllerDSL
|
4
|
+
|
5
|
+
#
|
6
|
+
# Initialize a new ControllerDSL
|
7
|
+
#
|
8
|
+
# @param controller [Moonrope::Controller]
|
9
|
+
#
|
10
|
+
def initialize(controller)
|
11
|
+
@controller = controller
|
12
|
+
end
|
13
|
+
|
14
|
+
# @return [Moonrope::Controller] the associated controller
|
15
|
+
attr_reader :controller
|
16
|
+
|
17
|
+
#
|
18
|
+
# Defines a new action within the controller.
|
19
|
+
#
|
20
|
+
# @param name [Symbol]
|
21
|
+
# @yield instance evals the block within the ActionDSL
|
22
|
+
# @return [Moonrope::Action] the new action instance
|
23
|
+
#
|
24
|
+
def action(name, &block)
|
25
|
+
action = Moonrope::Action.new(@controller, name)
|
26
|
+
action.dsl.instance_eval(&block) if block_given?
|
27
|
+
@controller.actions[name] = action
|
28
|
+
action
|
29
|
+
end
|
30
|
+
|
31
|
+
#
|
32
|
+
# Defines a new before action within the controller.
|
33
|
+
#
|
34
|
+
# @param actions [Symbol] the names of the actions to apply to (none for all)
|
35
|
+
# @yield stores the block as the block to be executed
|
36
|
+
# @return [Moonrope::BeforeAction]
|
37
|
+
#
|
38
|
+
def before(*actions, &block)
|
39
|
+
before_action = Moonrope::BeforeAction.new(@controller)
|
40
|
+
before_action.block = block
|
41
|
+
before_action.actions = actions
|
42
|
+
@controller.befores << before_action
|
43
|
+
before_action
|
44
|
+
end
|
45
|
+
|
46
|
+
#
|
47
|
+
# Defines a new helper for this controller.
|
48
|
+
#
|
49
|
+
# @param name [Symbol] the name of the helper
|
50
|
+
# @yield stores the block to execute for the helper
|
51
|
+
#
|
52
|
+
def helper(name, &block)
|
53
|
+
@controller.base.helpers << Moonrope::Helper.new(name, @controller, &block)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
@@ -0,0 +1,63 @@
|
|
1
|
+
module Moonrope
|
2
|
+
module DSL
|
3
|
+
class StructureDSL
|
4
|
+
|
5
|
+
#
|
6
|
+
# Initialize a new StructureDSL
|
7
|
+
#
|
8
|
+
# @param structure [Moonrope::Structure]
|
9
|
+
#
|
10
|
+
def initialize(structure)
|
11
|
+
@structure = structure
|
12
|
+
end
|
13
|
+
|
14
|
+
# @return [Moonrope::Structure] the associated structure
|
15
|
+
attr_reader :structure
|
16
|
+
|
17
|
+
#
|
18
|
+
# Set the basic variables for the structure.
|
19
|
+
#
|
20
|
+
# @yield stores the contents of the block for the basic data
|
21
|
+
# @return [void]
|
22
|
+
#
|
23
|
+
def basic(&block)
|
24
|
+
structure.basic = block
|
25
|
+
end
|
26
|
+
|
27
|
+
#
|
28
|
+
# Set the full variables for the structure.
|
29
|
+
#
|
30
|
+
# @yield stores the contents of the block for the full data
|
31
|
+
# @return [void]
|
32
|
+
#
|
33
|
+
def full(&block)
|
34
|
+
structure.full = block
|
35
|
+
end
|
36
|
+
|
37
|
+
#
|
38
|
+
# Add a new expansion.
|
39
|
+
#
|
40
|
+
# @param name [Symbol] the name of the expansion
|
41
|
+
# @yield sets the block to execute for the expansion if requested
|
42
|
+
# @return [void]
|
43
|
+
#
|
44
|
+
def expansion(name, &block)
|
45
|
+
structure.expansions[name] = block
|
46
|
+
end
|
47
|
+
|
48
|
+
#
|
49
|
+
# Add a new restricted block.
|
50
|
+
#
|
51
|
+
# @yield instance evals the block within RestrictionDSL
|
52
|
+
# @return [Moonrope::DSL::RestrictionDSL]
|
53
|
+
#
|
54
|
+
def restricted(&block)
|
55
|
+
dsl = Moonrope::DSL::StructureRestrictionDSL.new
|
56
|
+
dsl.instance_eval(&block)
|
57
|
+
structure.restrictions << dsl
|
58
|
+
dsl
|
59
|
+
end
|
60
|
+
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module Moonrope
|
2
|
+
module DSL
|
3
|
+
class StructureRestrictionDSL
|
4
|
+
|
5
|
+
#
|
6
|
+
# Set or get the data block for the restriction
|
7
|
+
#
|
8
|
+
# @yield stores the contents of the block as the data
|
9
|
+
# @return [Proc]
|
10
|
+
#
|
11
|
+
def data(&block)
|
12
|
+
block_given? ? @data = block : @data
|
13
|
+
end
|
14
|
+
|
15
|
+
#
|
16
|
+
# Set or get the condition block for the restriction
|
17
|
+
#
|
18
|
+
# @yield stores the contents of the block as the condition
|
19
|
+
# @return [Proc]
|
20
|
+
#
|
21
|
+
def condition(&block)
|
22
|
+
block_given? ? @condition = block : @condition
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
module Moonrope
|
2
|
+
module Errors
|
3
|
+
|
4
|
+
class Error < StandardError
|
5
|
+
end
|
6
|
+
|
7
|
+
class RequestError < Error
|
8
|
+
attr_reader :options
|
9
|
+
|
10
|
+
def initialize(options)
|
11
|
+
@options = options
|
12
|
+
end
|
13
|
+
|
14
|
+
def data
|
15
|
+
{:message => @options}
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
class AccessDenied < RequestError
|
20
|
+
def status
|
21
|
+
'access-denied'
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
class NotFound < RequestError
|
26
|
+
def status
|
27
|
+
'not-found'
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
class ValidationError < RequestError
|
32
|
+
def status
|
33
|
+
'validation-error'
|
34
|
+
end
|
35
|
+
|
36
|
+
def data
|
37
|
+
{:errors => @options}
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
class ParameterError < RequestError
|
42
|
+
def status
|
43
|
+
'parameter-error'
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,141 @@
|
|
1
|
+
module Moonrope
|
2
|
+
class EvalEnvironment
|
3
|
+
|
4
|
+
include Moonrope::EvalHelpers
|
5
|
+
|
6
|
+
# @return [Moonrope::Base] the base object
|
7
|
+
attr_reader :base
|
8
|
+
|
9
|
+
# @return [Moonrope::Request] the associated request
|
10
|
+
attr_reader :request
|
11
|
+
|
12
|
+
# @return [Hash] the headers
|
13
|
+
attr_reader :headers
|
14
|
+
|
15
|
+
# @return [Hash] the flags
|
16
|
+
attr_reader :flags
|
17
|
+
|
18
|
+
# @return [Hash] the default params to be merged with request params
|
19
|
+
attr_accessor :default_params
|
20
|
+
|
21
|
+
# @return [Moonrope::Action] the action which invoked this environment
|
22
|
+
attr_accessor :action
|
23
|
+
|
24
|
+
#
|
25
|
+
# Initialize a new EvalEnvironment
|
26
|
+
#
|
27
|
+
# @param base [Moonrope::Base]
|
28
|
+
# @param request [Moonrope::Request]
|
29
|
+
# @param accessors [Hash] additional variables which can be made available
|
30
|
+
#
|
31
|
+
def initialize(base, request, accessors = {})
|
32
|
+
@base = base
|
33
|
+
@request = request
|
34
|
+
@accessors = accessors
|
35
|
+
@default_params = {}
|
36
|
+
reset
|
37
|
+
end
|
38
|
+
|
39
|
+
#
|
40
|
+
# @return [Integer] the requested API version
|
41
|
+
#
|
42
|
+
def version
|
43
|
+
request ? request.version : 1
|
44
|
+
end
|
45
|
+
|
46
|
+
#
|
47
|
+
# @return [Object] the authenticated object
|
48
|
+
#
|
49
|
+
def auth
|
50
|
+
request ? request.authenticated_user : nil
|
51
|
+
end
|
52
|
+
|
53
|
+
#
|
54
|
+
# @return [Hash] all parameters sent for this request including defaults
|
55
|
+
#
|
56
|
+
def params
|
57
|
+
@params ||= begin
|
58
|
+
params = request ? request.params : ParamSet.new
|
59
|
+
params._defaults = @default_params
|
60
|
+
params
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
#
|
65
|
+
# Set a header which should be returned to the client.
|
66
|
+
#
|
67
|
+
# @param name [String] the key
|
68
|
+
# @param value [String] the value
|
69
|
+
# @return [void]
|
70
|
+
#
|
71
|
+
def set_header(name, value)
|
72
|
+
@headers[name.to_s] = value
|
73
|
+
end
|
74
|
+
|
75
|
+
#
|
76
|
+
# Set a flag which should be returned to the client.
|
77
|
+
#
|
78
|
+
# @param name [Symbol] the key
|
79
|
+
# @param value [String] the value
|
80
|
+
# @return [void]
|
81
|
+
#
|
82
|
+
def set_flag(name, value)
|
83
|
+
@flags[name] = value
|
84
|
+
end
|
85
|
+
|
86
|
+
#
|
87
|
+
# Clear all flags & headers from this environment.
|
88
|
+
#
|
89
|
+
# @return [void]
|
90
|
+
#
|
91
|
+
def reset
|
92
|
+
@flags = {}
|
93
|
+
@headers = {}
|
94
|
+
end
|
95
|
+
|
96
|
+
#
|
97
|
+
# Attempts to find an return an accessor from the has
|
98
|
+
#
|
99
|
+
# @param name [Symbol] the name of the method
|
100
|
+
# @param value [void] unused/wnated
|
101
|
+
# @return [Object]
|
102
|
+
#
|
103
|
+
def method_missing(name, *args)
|
104
|
+
if @accessors.keys.include?(name.to_sym)
|
105
|
+
@accessors[name.to_sym]
|
106
|
+
elsif helper = @base.helper(name.to_sym, action ? action.controller : nil)
|
107
|
+
instance_exec(*args, &helper.block)
|
108
|
+
else
|
109
|
+
super
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
#
|
114
|
+
# Generate a new structure from the core DSL for the given
|
115
|
+
# object and return a hash or nil if the structure doesn't
|
116
|
+
# exist.
|
117
|
+
#
|
118
|
+
# @param structure [Moonrope::Structure or Symbol] the structure to be used
|
119
|
+
# @param object [Object] the object to pass through the structure
|
120
|
+
# @param options [Hash] options to pass to the strucutre hash generator
|
121
|
+
#
|
122
|
+
def structure(structure, object, options = {})
|
123
|
+
if object
|
124
|
+
structure = case structure
|
125
|
+
when Symbol, String then @base.structure(structure.to_sym)
|
126
|
+
when Moonrope::Structure then structure
|
127
|
+
else
|
128
|
+
raise Moonrope::Errors::Error, "Invalid structure '#{structure}'"
|
129
|
+
end
|
130
|
+
if structure
|
131
|
+
structure.hash(object, options.merge(:request => @request))
|
132
|
+
else
|
133
|
+
raise Moonrope::Errors::Error, "No structure found named '#{structure}'"
|
134
|
+
end
|
135
|
+
else
|
136
|
+
nil
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
end
|
141
|
+
end
|