moonrope 1.1.4 → 1.2.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 +4 -4
- data/lib/moonrope/action.rb +24 -5
- data/lib/moonrope/dsl/structure_dsl.rb +63 -42
- data/lib/moonrope/structure.rb +98 -18
- data/lib/moonrope/structure_attribute.rb +26 -0
- data/lib/moonrope/version.rb +1 -1
- data/lib/moonrope.rb +2 -1
- metadata +17 -3
- data/lib/moonrope/dsl/structure_restriction_dsl.rb +0 -27
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA1:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: aaca3dee3108ec017c94921848e0cf7bf5de4136
|
|
4
|
+
data.tar.gz: 703c784363fe0cc329931c7568c5603b1b863bef
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: e28959e2e988a35fbb030b944dafeb086b0c973f9691cc23c2c0d23cf63fb2b3cc03b776af60c7e6022241b749ee6fb85b6f9d78fedc03c90c61bba2f4e9df53
|
|
7
|
+
data.tar.gz: e5917f0184a0113189a5291b6a91240c987dd52d9725728d57ab69e9cffaedd2f7148ce01b67a79f326c714859f3c9c1d8e2112301a6641ae1a43b46a6abefb8
|
data/lib/moonrope/action.rb
CHANGED
|
@@ -147,12 +147,31 @@ module Moonrope
|
|
|
147
147
|
eval_environment = EvalEnvironment.new(@controller.base, request)
|
|
148
148
|
end
|
|
149
149
|
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
150
|
+
access_condition = self.access || @controller.base.default_access
|
|
151
|
+
|
|
152
|
+
if eval_environment.auth
|
|
153
|
+
# If there's no authentication object, access is permitted otherwise
|
|
154
|
+
# we'll do the normal testing.
|
|
155
|
+
if access_condition.is_a?(Proc)
|
|
156
|
+
!!eval_environment.instance_exec(self, &access_condition)
|
|
157
|
+
elsif access_condition.is_a?(Symbol)
|
|
158
|
+
!!(eval_environment.auth.respond_to?(access_condition) && eval_environment.auth.send(access_condition))
|
|
159
|
+
elsif access_condition.is_a?(Hash) && access_condition[:must_be] && access_condition[:with]
|
|
160
|
+
!!(eval_environment.auth.is_a?(access_condition[:must_be]) &&
|
|
161
|
+
eval_environment.auth.respond_to?(access_condition[:with]) &&
|
|
162
|
+
eval_environment.auth.send(access_condition[:with])
|
|
163
|
+
)
|
|
164
|
+
elsif access_condition.is_a?(Hash) && access_condition[:must_be]
|
|
165
|
+
!!(eval_environment.auth.is_a?(access_condition[:must_be]))
|
|
166
|
+
elsif access_condition == true
|
|
167
|
+
true
|
|
168
|
+
else
|
|
169
|
+
false
|
|
170
|
+
end
|
|
154
171
|
else
|
|
155
|
-
|
|
172
|
+
# No authentication object is available to test with. The result here
|
|
173
|
+
# depends on whether or not an access condition has been defined or not.
|
|
174
|
+
!access_condition
|
|
156
175
|
end
|
|
157
176
|
end
|
|
158
177
|
|
|
@@ -2,6 +2,18 @@ module Moonrope
|
|
|
2
2
|
module DSL
|
|
3
3
|
class StructureDSL
|
|
4
4
|
|
|
5
|
+
# @return [Moonrope::Structure] the associated structure
|
|
6
|
+
attr_reader :structure
|
|
7
|
+
|
|
8
|
+
# @return [Array] groups which should applied
|
|
9
|
+
attr_accessor :groups
|
|
10
|
+
|
|
11
|
+
# @return [Array] conditions which should applied
|
|
12
|
+
attr_accessor :conditions
|
|
13
|
+
|
|
14
|
+
# @return [Hash] options
|
|
15
|
+
attr_accessor :options
|
|
16
|
+
|
|
5
17
|
#
|
|
6
18
|
# Initialize a new StructureDSL
|
|
7
19
|
#
|
|
@@ -9,53 +21,62 @@ module Moonrope
|
|
|
9
21
|
#
|
|
10
22
|
def initialize(structure)
|
|
11
23
|
@structure = structure
|
|
24
|
+
@options = {}
|
|
25
|
+
@groups = []
|
|
26
|
+
@conditions = []
|
|
12
27
|
end
|
|
13
28
|
|
|
14
|
-
|
|
15
|
-
|
|
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
|
|
29
|
+
def scope(options = {}, &block)
|
|
30
|
+
scope_dsl = self.class.new(@structure)
|
|
31
|
+
scope_dsl.options = options
|
|
32
|
+
scope_dsl.instance_eval(&block)
|
|
25
33
|
end
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
# @return [void]
|
|
32
|
-
#
|
|
33
|
-
def full(&block)
|
|
34
|
-
structure.full = block
|
|
34
|
+
|
|
35
|
+
def group(name, &block)
|
|
36
|
+
scope_dsl = self.class.new(@structure)
|
|
37
|
+
scope_dsl.groups = [@groups, name].flatten
|
|
38
|
+
scope_dsl.instance_eval(&block)
|
|
35
39
|
end
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
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
|
|
40
|
+
|
|
41
|
+
def condition(condition, &block)
|
|
42
|
+
scope_dsl = self.class.new(@structure)
|
|
43
|
+
scope_dsl.conditions = [@conditions, condition].flatten
|
|
44
|
+
scope_dsl.instance_eval(&block)
|
|
46
45
|
end
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
46
|
+
|
|
47
|
+
def attribute(type, name, description, options = {})
|
|
48
|
+
attribute = StructureAttribute.new(type, name, description)
|
|
49
|
+
attribute.structure = options[:structure]
|
|
50
|
+
attribute.structure_opts = options[:structure_opts]
|
|
51
|
+
attribute.value_type = options[:type]
|
|
52
|
+
attribute.source_attribute = options[:source] || options[:name]
|
|
53
|
+
attribute.groups = @groups
|
|
54
|
+
attribute.conditions = @conditions
|
|
55
|
+
@structure.attributes[type] << attribute
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
def basic(*args, &block)
|
|
59
|
+
if block_given?
|
|
60
|
+
@structure.basic = block
|
|
61
|
+
else
|
|
62
|
+
attribute(:basic, *args)
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
def full(*args, &block)
|
|
67
|
+
if block_given?
|
|
68
|
+
@structure.full = block
|
|
69
|
+
else
|
|
70
|
+
attribute(:full, *args)
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
def expansion(name, *args, &block)
|
|
75
|
+
if block_given?
|
|
76
|
+
@structure.expansions[name] = block
|
|
77
|
+
else
|
|
78
|
+
attribute(:expansion, name, *args)
|
|
79
|
+
end
|
|
59
80
|
end
|
|
60
81
|
|
|
61
82
|
end
|
data/lib/moonrope/structure.rb
CHANGED
|
@@ -16,12 +16,12 @@ module Moonrope
|
|
|
16
16
|
# @return [Hash] all expansions for the structure
|
|
17
17
|
attr_reader :expansions
|
|
18
18
|
|
|
19
|
-
# @return [Array] all restrictions for the structure
|
|
20
|
-
attr_reader :restrictions
|
|
21
|
-
|
|
22
19
|
# @return [Moonrope::Base] the base API
|
|
23
20
|
attr_reader :base
|
|
24
21
|
|
|
22
|
+
# @return [Hash] attributes which should be included in this structure
|
|
23
|
+
attr_reader :attributes
|
|
24
|
+
|
|
25
25
|
#
|
|
26
26
|
# Initialize a new structure
|
|
27
27
|
#
|
|
@@ -32,7 +32,7 @@ module Moonrope
|
|
|
32
32
|
@base = base
|
|
33
33
|
@name = name
|
|
34
34
|
@expansions = {}
|
|
35
|
-
@
|
|
35
|
+
@attributes = {:basic => [], :full => [], :expansion => []}
|
|
36
36
|
@dsl = Moonrope::DSL::StructureDSL.new(self)
|
|
37
37
|
@dsl.instance_eval(&block) if block_given?
|
|
38
38
|
end
|
|
@@ -45,33 +45,45 @@ module Moonrope
|
|
|
45
45
|
# @return [Hash]
|
|
46
46
|
#
|
|
47
47
|
def hash(object, options = {})
|
|
48
|
-
# Set up an environment
|
|
48
|
+
# Set up an environment
|
|
49
49
|
environment = EvalEnvironment.new(base, options[:request], :o => object)
|
|
50
|
-
|
|
50
|
+
|
|
51
|
+
# Set a new hash
|
|
52
|
+
hash = Hash.new
|
|
53
|
+
|
|
54
|
+
# Add the 'basic' structured fields
|
|
55
|
+
hash.deep_merge! hash_for_attributes(@attributes[:basic], object, environment)
|
|
56
|
+
|
|
51
57
|
# Always get a basic hash to work from
|
|
52
|
-
|
|
58
|
+
if self.basic.is_a?(Proc)
|
|
59
|
+
hash.deep_merge! environment.instance_eval(&self.basic)
|
|
60
|
+
end
|
|
53
61
|
|
|
54
62
|
# Enhance with the full hash if requested
|
|
55
63
|
if options[:full]
|
|
64
|
+
|
|
65
|
+
# Add the 'full' structured fields
|
|
66
|
+
hash.deep_merge! hash_for_attributes(@attributes[:full], object, environment)
|
|
67
|
+
|
|
56
68
|
if self.full.is_a?(Proc)
|
|
57
69
|
full_hash = environment.instance_eval(&self.full)
|
|
58
|
-
hash.
|
|
59
|
-
end
|
|
60
|
-
|
|
61
|
-
# Add restrictions
|
|
62
|
-
if environment.auth
|
|
63
|
-
@restrictions.each do |restriction|
|
|
64
|
-
next unless environment.instance_eval(&restriction.condition) == true
|
|
65
|
-
hash.merge!(environment.instance_eval(&restriction.data))
|
|
66
|
-
end
|
|
70
|
+
hash.deep_merge! full_hash
|
|
67
71
|
end
|
|
68
72
|
end
|
|
69
73
|
|
|
70
74
|
# Add expansions
|
|
71
|
-
if options[:expansions]
|
|
75
|
+
if options[:expansions]
|
|
76
|
+
|
|
77
|
+
# Add structured expansions
|
|
78
|
+
@attributes[:expansion].each do |attribute|
|
|
79
|
+
next if options[:expansions].is_a?(Array) && !options[:expansions].include?(name.to_sym)
|
|
80
|
+
hash.deep_merge!(hash_for_attributes([attribute], object, environment))
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
# Add the expansions
|
|
72
84
|
expansions.each do |name, expansion|
|
|
73
85
|
next if options[:expansions].is_a?(Array) && !options[:expansions].include?(name.to_sym)
|
|
74
|
-
hash.
|
|
86
|
+
hash.deep_merge!(name.to_sym => environment.instance_eval(&expansion))
|
|
75
87
|
end
|
|
76
88
|
end
|
|
77
89
|
|
|
@@ -79,5 +91,73 @@ module Moonrope
|
|
|
79
91
|
hash
|
|
80
92
|
end
|
|
81
93
|
|
|
94
|
+
private
|
|
95
|
+
|
|
96
|
+
#
|
|
97
|
+
# Return a returnable hash for a given set of structured fields.
|
|
98
|
+
#
|
|
99
|
+
def hash_for_attributes(attributes, object, environment)
|
|
100
|
+
return {} unless attributes.is_a?(Array)
|
|
101
|
+
Hash.new.tap do |hash|
|
|
102
|
+
attributes.each do |attribute|
|
|
103
|
+
|
|
104
|
+
unless attribute.conditions.empty?
|
|
105
|
+
matched = false
|
|
106
|
+
attribute.conditions.each do |condition|
|
|
107
|
+
if !environment.instance_eval(&condition)
|
|
108
|
+
matched = true
|
|
109
|
+
break
|
|
110
|
+
end
|
|
111
|
+
end
|
|
112
|
+
if matched
|
|
113
|
+
# Skip this item because a condition didn't evaluate
|
|
114
|
+
# to true.
|
|
115
|
+
next
|
|
116
|
+
end
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
value = value_for_attribute(object, environment, attribute)
|
|
120
|
+
|
|
121
|
+
if attribute.groups.empty?
|
|
122
|
+
hash[attribute.name] = value
|
|
123
|
+
else
|
|
124
|
+
last_hash = hash
|
|
125
|
+
attribute.groups.each_with_index do |group, index|
|
|
126
|
+
last_hash[group] ||= {}
|
|
127
|
+
if index == attribute.groups.size - 1
|
|
128
|
+
last_hash[group][attribute.name] = value
|
|
129
|
+
end
|
|
130
|
+
last_hash = last_hash[group]
|
|
131
|
+
end
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
end
|
|
135
|
+
end
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
#
|
|
139
|
+
# Return a value for a structured field.
|
|
140
|
+
#
|
|
141
|
+
def value_for_attribute(object, environment, attribute)
|
|
142
|
+
value = object.send(attribute.source_attribute)
|
|
143
|
+
if attribute.structure
|
|
144
|
+
# If a structure is required, lookup the desired structure and set the
|
|
145
|
+
# hash value as appropriate.
|
|
146
|
+
if structure = self.base.structure(attribute.structure)
|
|
147
|
+
structure_opts = attribute.structure_opts || {}
|
|
148
|
+
if value.is_a?(Array)
|
|
149
|
+
value.map do |v|
|
|
150
|
+
structure.hash(v, structure_opts.merge(:request => environment.request))
|
|
151
|
+
end
|
|
152
|
+
else
|
|
153
|
+
structure.hash(value, structure_opts.merge(:request => environment.request))
|
|
154
|
+
end
|
|
155
|
+
end
|
|
156
|
+
else
|
|
157
|
+
# Return the value as normal for non-structure values.
|
|
158
|
+
value
|
|
159
|
+
end
|
|
160
|
+
end
|
|
161
|
+
|
|
82
162
|
end
|
|
83
163
|
end
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
module Moonrope
|
|
2
|
+
class StructureAttribute
|
|
3
|
+
|
|
4
|
+
attr_accessor :name
|
|
5
|
+
attr_accessor :groups
|
|
6
|
+
attr_accessor :conditions
|
|
7
|
+
attr_accessor :source_attribute
|
|
8
|
+
attr_accessor :description
|
|
9
|
+
attr_accessor :value_type
|
|
10
|
+
attr_accessor :structure
|
|
11
|
+
attr_accessor :structure_opts
|
|
12
|
+
|
|
13
|
+
def initialize(type, name, description)
|
|
14
|
+
@type = type
|
|
15
|
+
@name = name
|
|
16
|
+
@description = description
|
|
17
|
+
@groups = []
|
|
18
|
+
@conditions = []
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def source_attribute
|
|
22
|
+
@source_attribute || @name
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
end
|
|
26
|
+
end
|
data/lib/moonrope/version.rb
CHANGED
data/lib/moonrope.rb
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
require 'json'
|
|
2
2
|
require 'logger'
|
|
3
|
+
require 'deep_merge'
|
|
3
4
|
|
|
4
5
|
require 'moonrope/action'
|
|
5
6
|
require 'moonrope/action_result'
|
|
@@ -10,7 +11,6 @@ require 'moonrope/dsl/base_dsl'
|
|
|
10
11
|
require 'moonrope/dsl/action_dsl'
|
|
11
12
|
require 'moonrope/dsl/controller_dsl'
|
|
12
13
|
require 'moonrope/dsl/structure_dsl'
|
|
13
|
-
require 'moonrope/dsl/structure_restriction_dsl'
|
|
14
14
|
|
|
15
15
|
require 'moonrope/errors'
|
|
16
16
|
require 'moonrope/eval_helpers'
|
|
@@ -20,6 +20,7 @@ require 'moonrope/param_set'
|
|
|
20
20
|
require 'moonrope/rack_middleware'
|
|
21
21
|
require 'moonrope/request'
|
|
22
22
|
require 'moonrope/structure'
|
|
23
|
+
require 'moonrope/structure_attribute'
|
|
23
24
|
require 'moonrope/version'
|
|
24
25
|
|
|
25
26
|
require 'moonrope/railtie' if defined?(Rails)
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: moonrope
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.
|
|
4
|
+
version: 1.2.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Adam Cooke
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2014-
|
|
11
|
+
date: 2014-07-01 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: json
|
|
@@ -38,6 +38,20 @@ dependencies:
|
|
|
38
38
|
- - "~>"
|
|
39
39
|
- !ruby/object:Gem::Version
|
|
40
40
|
version: '1.4'
|
|
41
|
+
- !ruby/object:Gem::Dependency
|
|
42
|
+
name: deep_merge
|
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
|
44
|
+
requirements:
|
|
45
|
+
- - "~>"
|
|
46
|
+
- !ruby/object:Gem::Version
|
|
47
|
+
version: '1.0'
|
|
48
|
+
type: :runtime
|
|
49
|
+
prerelease: false
|
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
51
|
+
requirements:
|
|
52
|
+
- - "~>"
|
|
53
|
+
- !ruby/object:Gem::Version
|
|
54
|
+
version: '1.0'
|
|
41
55
|
- !ruby/object:Gem::Dependency
|
|
42
56
|
name: rake
|
|
43
57
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -113,7 +127,6 @@ files:
|
|
|
113
127
|
- lib/moonrope/dsl/base_dsl.rb
|
|
114
128
|
- lib/moonrope/dsl/controller_dsl.rb
|
|
115
129
|
- lib/moonrope/dsl/structure_dsl.rb
|
|
116
|
-
- lib/moonrope/dsl/structure_restriction_dsl.rb
|
|
117
130
|
- lib/moonrope/errors.rb
|
|
118
131
|
- lib/moonrope/eval_environment.rb
|
|
119
132
|
- lib/moonrope/eval_helpers.rb
|
|
@@ -123,6 +136,7 @@ files:
|
|
|
123
136
|
- lib/moonrope/railtie.rb
|
|
124
137
|
- lib/moonrope/request.rb
|
|
125
138
|
- lib/moonrope/structure.rb
|
|
139
|
+
- lib/moonrope/structure_attribute.rb
|
|
126
140
|
- lib/moonrope/version.rb
|
|
127
141
|
homepage: http://adamcooke.io
|
|
128
142
|
licenses:
|
|
@@ -1,27 +0,0 @@
|
|
|
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
|