moonrope 1.0.0
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 +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
|