servies 0.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.
- data/lib/generators/servies/install_generator.rb +17 -0
- data/lib/generators/servies/templates/backend/backend.rb +3 -0
- data/lib/generators/servies/templates/backend/command.rb +3 -0
- data/lib/generators/servies/templates/backend/interactor.rb +16 -0
- data/lib/generators/servies/templates/backend/query.rb +3 -0
- data/lib/servies.rb +19 -0
- data/lib/servies/access_denied.rb +4 -0
- data/lib/servies/backend.rb +23 -0
- data/lib/servies/engine.rb +6 -0
- data/lib/servies/operation.rb +77 -0
- data/lib/servies/operation_finder.rb +34 -0
- data/lib/servies/validation_error.rb +4 -0
- data/lib/servies/validations.rb +45 -0
- data/lib/servies/version.rb +3 -0
- metadata +257 -0
@@ -0,0 +1,17 @@
|
|
1
|
+
require 'rails/generators'
|
2
|
+
|
3
|
+
module Servies
|
4
|
+
class InstallGenerator < Rails::Generators::Base
|
5
|
+
def self.source_root
|
6
|
+
@source_root ||= File.expand_path(File.join(File.dirname(__FILE__), 'templates'))
|
7
|
+
end
|
8
|
+
|
9
|
+
def copy_backend_directory
|
10
|
+
directory 'backend', 'app/backend', recursive: true
|
11
|
+
end
|
12
|
+
|
13
|
+
def add_backend_to_autoload_paths
|
14
|
+
application "config.autoload_paths += %W(\#{config.root}/app/backend)"
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
class Interactor
|
2
|
+
include Servies::Operation
|
3
|
+
|
4
|
+
# If you want your interactors to be compatible with a backgrounding
|
5
|
+
# daemon, you can use this base class to add support.
|
6
|
+
#
|
7
|
+
# Example for Resque:
|
8
|
+
#
|
9
|
+
# def self.perform(*args)
|
10
|
+
# new(*args).call
|
11
|
+
# end
|
12
|
+
|
13
|
+
def authorized?
|
14
|
+
raise NotImplementedError
|
15
|
+
end
|
16
|
+
end
|
data/lib/servies.rb
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
module Servies
|
2
|
+
# this method is also available as constantize in Rails,
|
3
|
+
# but we want to be able to write classes and/or tests without Rails
|
4
|
+
def self.get_class_by_string classname
|
5
|
+
classname.constantize
|
6
|
+
end
|
7
|
+
|
8
|
+
def self.string_to_classname string
|
9
|
+
string.to_s.camelize
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
require_relative 'servies/engine' if defined?(Rails)
|
14
|
+
require_relative 'servies/access_denied'
|
15
|
+
require_relative 'servies/validation_error'
|
16
|
+
require_relative 'servies/validations'
|
17
|
+
require_relative 'servies/backend'
|
18
|
+
require_relative 'servies/operation'
|
19
|
+
require_relative 'servies/version'
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'servies/operation_finder'
|
2
|
+
|
3
|
+
module Servies
|
4
|
+
class Backend
|
5
|
+
attr_reader :context
|
6
|
+
|
7
|
+
def initialize(context = {})
|
8
|
+
@context = context
|
9
|
+
end
|
10
|
+
|
11
|
+
def interactors
|
12
|
+
OperationFinder.new("Interactors", self, false)
|
13
|
+
end
|
14
|
+
|
15
|
+
def queries
|
16
|
+
OperationFinder.new("Queries", self, true)
|
17
|
+
end
|
18
|
+
|
19
|
+
def commands
|
20
|
+
OperationFinder.new("Commands", self, true)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,77 @@
|
|
1
|
+
require 'active_support/concern'
|
2
|
+
require 'servies/validations'
|
3
|
+
require 'virtus'
|
4
|
+
require_relative 'access_denied'
|
5
|
+
|
6
|
+
module Servies
|
7
|
+
module Operation
|
8
|
+
include ActiveSupport::Concern
|
9
|
+
include Servies::Validations
|
10
|
+
include Virtus
|
11
|
+
|
12
|
+
attribute :backend, ::Servies::Backend
|
13
|
+
|
14
|
+
def validate
|
15
|
+
return false unless attributes_without_defaults_have_values
|
16
|
+
if respond_to? :valid?
|
17
|
+
raise Servies::ValidationError, "an argument is invalid" unless valid?
|
18
|
+
else
|
19
|
+
true
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def call(*args, &block)
|
24
|
+
validate
|
25
|
+
check_authorization
|
26
|
+
execute(*args, &block)
|
27
|
+
end
|
28
|
+
|
29
|
+
private
|
30
|
+
|
31
|
+
def commands
|
32
|
+
backend.commands
|
33
|
+
end
|
34
|
+
|
35
|
+
def queries
|
36
|
+
backend.queries
|
37
|
+
end
|
38
|
+
|
39
|
+
def interactors
|
40
|
+
backend.interactors
|
41
|
+
end
|
42
|
+
|
43
|
+
def context
|
44
|
+
backend.context
|
45
|
+
end
|
46
|
+
|
47
|
+
def servies_options
|
48
|
+
@options
|
49
|
+
end
|
50
|
+
|
51
|
+
def raise_unauthorized(message='Unauthorized')
|
52
|
+
raise Servies::AccessDenied, message
|
53
|
+
end
|
54
|
+
|
55
|
+
def check_authorization
|
56
|
+
raise_unauthorized if respond_to? :authorized?, true and not authorized?
|
57
|
+
end
|
58
|
+
|
59
|
+
def attributes_without_defaults_have_values
|
60
|
+
attributes_without_value = attribute_set.select do |attribute|
|
61
|
+
not attribute.options.has_key?(:default) and send(attribute.name).nil?
|
62
|
+
end
|
63
|
+
attributes_without_value.empty?
|
64
|
+
end
|
65
|
+
|
66
|
+
module ClassMethods
|
67
|
+
# make our interactors behave as Resque jobs
|
68
|
+
def perform(*args)
|
69
|
+
new(*args).call
|
70
|
+
end
|
71
|
+
|
72
|
+
def queue
|
73
|
+
@queue || :interactor_operations
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
require 'active_support/inflector'
|
2
|
+
|
3
|
+
module Servies
|
4
|
+
class OperationFinder
|
5
|
+
attr_reader :namespace, :backend
|
6
|
+
|
7
|
+
def initialize(namespace, backend, autocall = false)
|
8
|
+
@namespace = namespace
|
9
|
+
@backend = backend
|
10
|
+
@autocall = autocall
|
11
|
+
end
|
12
|
+
|
13
|
+
def method_missing(name, attributes = {})
|
14
|
+
klass = _find_klass(name)
|
15
|
+
instance = klass.new(attributes.merge(backend: backend))
|
16
|
+
|
17
|
+
if @autocall
|
18
|
+
instance.call
|
19
|
+
else
|
20
|
+
instance
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def respond_to_missing?(name, include_private = false)
|
25
|
+
_find_klass(name)
|
26
|
+
end
|
27
|
+
|
28
|
+
private
|
29
|
+
|
30
|
+
def _find_klass(name)
|
31
|
+
namespace.constantize.const_get(name.to_s.camelize)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
require 'servies/validation_error'
|
2
|
+
|
3
|
+
module Servies
|
4
|
+
module Validations
|
5
|
+
def validate_hexadecimal_string param_name, param
|
6
|
+
#warn "[DEPRECATION] `validate_hexadecimal_string` is deprecated. Please use the ActiveModel validation instead."
|
7
|
+
raise Servies::ValidationError, "#{param_name.to_s} should be an hexadecimal string." unless param.is_a? String and /\A[\da-fA-F]+\Z/.match param
|
8
|
+
end
|
9
|
+
|
10
|
+
def validate_regex param_name, param, regex, message
|
11
|
+
#warn "[DEPRECATION] `validate_integer` is deprecated. Please use the default format_of ActiveModel validator instead."
|
12
|
+
raise Servies::ValidationError, "#{param_name.to_s} #{message}" unless regex.match param
|
13
|
+
end
|
14
|
+
|
15
|
+
def validate_integer param_name, param, opts = {}
|
16
|
+
#warn "[DEPRECATION] `validate_integer` is deprecated. Please use the default numericality ActiveModel validator with the :only_integer option instead."
|
17
|
+
return if opts[:allow_blank] && param.blank?
|
18
|
+
raise Servies::ValidationError, "#{param_name.to_s} should be an integer." unless param.is_a? Integer
|
19
|
+
end
|
20
|
+
|
21
|
+
def validate_in_set param_name, param, set
|
22
|
+
raise Servies::ValidationError, "#{param_name.to_s} should be on of these values: #{set.inspect}." unless set.include? param
|
23
|
+
end
|
24
|
+
|
25
|
+
def validate_string param_name, param
|
26
|
+
#warn "[DEPRECATION] `validate_string` is deprecated. Please use the ActiveModel validation instead."
|
27
|
+
raise Servies::ValidationError, "#{param_name.to_s} should be a string." unless param.is_a? String
|
28
|
+
end
|
29
|
+
|
30
|
+
def validate_nonempty_string param_name, param
|
31
|
+
#warn "[DEPRECATION] `validate_string` is deprecated. Please use the ActiveModel validation with the :non_empty option instead."
|
32
|
+
raise Servies::ValidationError, "#{param_name.to_s} should be a nonempty string." unless param.is_a?(String) && not(param.nil?) && not(param.empty?)
|
33
|
+
end
|
34
|
+
|
35
|
+
def validate_integer_string param_name, param
|
36
|
+
#warn "[DEPRECATION] `validate_integer_string` is deprecated. Please use the ActiveModel validation instead."
|
37
|
+
raise Servies::ValidationError, "#{param_name.to_s} should be an integer string." unless param.is_a? String and /\A\d+\Z/.match param
|
38
|
+
end
|
39
|
+
|
40
|
+
def validate_not_nil param_name, param
|
41
|
+
#warn "[DEPRECATION] `validate_not_nil` is deprecated. Please use the default presence ActiveModel validator instead."
|
42
|
+
raise Servies::ValidationError, "#{param_name.to_s} should not be nil." if param.nil?
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
metadata
ADDED
@@ -0,0 +1,257 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: servies
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.2.0
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Marten Veldthuis
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2013-07-25 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: activesupport
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: 3.2.7
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ! '>='
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: 3.2.7
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: activemodel
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
34
|
+
requirements:
|
35
|
+
- - ! '>='
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: 3.2.7
|
38
|
+
type: :runtime
|
39
|
+
prerelease: false
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ! '>='
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: 3.2.7
|
46
|
+
- !ruby/object:Gem::Dependency
|
47
|
+
name: virtus
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
49
|
+
none: false
|
50
|
+
requirements:
|
51
|
+
- - '='
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: 0.5.5
|
54
|
+
type: :runtime
|
55
|
+
prerelease: false
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - '='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: 0.5.5
|
62
|
+
- !ruby/object:Gem::Dependency
|
63
|
+
name: rspec
|
64
|
+
requirement: !ruby/object:Gem::Requirement
|
65
|
+
none: false
|
66
|
+
requirements:
|
67
|
+
- - ~>
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: 2.14.0
|
70
|
+
type: :development
|
71
|
+
prerelease: false
|
72
|
+
version_requirements: !ruby/object:Gem::Requirement
|
73
|
+
none: false
|
74
|
+
requirements:
|
75
|
+
- - ~>
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
version: 2.14.0
|
78
|
+
- !ruby/object:Gem::Dependency
|
79
|
+
name: guard
|
80
|
+
requirement: !ruby/object:Gem::Requirement
|
81
|
+
none: false
|
82
|
+
requirements:
|
83
|
+
- - ! '>='
|
84
|
+
- !ruby/object:Gem::Version
|
85
|
+
version: '0'
|
86
|
+
type: :development
|
87
|
+
prerelease: false
|
88
|
+
version_requirements: !ruby/object:Gem::Requirement
|
89
|
+
none: false
|
90
|
+
requirements:
|
91
|
+
- - ! '>='
|
92
|
+
- !ruby/object:Gem::Version
|
93
|
+
version: '0'
|
94
|
+
- !ruby/object:Gem::Dependency
|
95
|
+
name: guard-bundler
|
96
|
+
requirement: !ruby/object:Gem::Requirement
|
97
|
+
none: false
|
98
|
+
requirements:
|
99
|
+
- - ! '>='
|
100
|
+
- !ruby/object:Gem::Version
|
101
|
+
version: '0'
|
102
|
+
type: :development
|
103
|
+
prerelease: false
|
104
|
+
version_requirements: !ruby/object:Gem::Requirement
|
105
|
+
none: false
|
106
|
+
requirements:
|
107
|
+
- - ! '>='
|
108
|
+
- !ruby/object:Gem::Version
|
109
|
+
version: '0'
|
110
|
+
- !ruby/object:Gem::Dependency
|
111
|
+
name: guard-rspec
|
112
|
+
requirement: !ruby/object:Gem::Requirement
|
113
|
+
none: false
|
114
|
+
requirements:
|
115
|
+
- - ! '>='
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: '0'
|
118
|
+
type: :development
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
none: false
|
122
|
+
requirements:
|
123
|
+
- - ! '>='
|
124
|
+
- !ruby/object:Gem::Version
|
125
|
+
version: '0'
|
126
|
+
- !ruby/object:Gem::Dependency
|
127
|
+
name: terminal-notifier-guard
|
128
|
+
requirement: !ruby/object:Gem::Requirement
|
129
|
+
none: false
|
130
|
+
requirements:
|
131
|
+
- - ! '>='
|
132
|
+
- !ruby/object:Gem::Version
|
133
|
+
version: '0'
|
134
|
+
type: :development
|
135
|
+
prerelease: false
|
136
|
+
version_requirements: !ruby/object:Gem::Requirement
|
137
|
+
none: false
|
138
|
+
requirements:
|
139
|
+
- - ! '>='
|
140
|
+
- !ruby/object:Gem::Version
|
141
|
+
version: '0'
|
142
|
+
- !ruby/object:Gem::Dependency
|
143
|
+
name: rb-fsevent
|
144
|
+
requirement: !ruby/object:Gem::Requirement
|
145
|
+
none: false
|
146
|
+
requirements:
|
147
|
+
- - ! '>='
|
148
|
+
- !ruby/object:Gem::Version
|
149
|
+
version: '0'
|
150
|
+
type: :development
|
151
|
+
prerelease: false
|
152
|
+
version_requirements: !ruby/object:Gem::Requirement
|
153
|
+
none: false
|
154
|
+
requirements:
|
155
|
+
- - ! '>='
|
156
|
+
- !ruby/object:Gem::Version
|
157
|
+
version: '0'
|
158
|
+
- !ruby/object:Gem::Dependency
|
159
|
+
name: rake
|
160
|
+
requirement: !ruby/object:Gem::Requirement
|
161
|
+
none: false
|
162
|
+
requirements:
|
163
|
+
- - ! '>='
|
164
|
+
- !ruby/object:Gem::Version
|
165
|
+
version: '0'
|
166
|
+
type: :development
|
167
|
+
prerelease: false
|
168
|
+
version_requirements: !ruby/object:Gem::Requirement
|
169
|
+
none: false
|
170
|
+
requirements:
|
171
|
+
- - ! '>='
|
172
|
+
- !ruby/object:Gem::Version
|
173
|
+
version: '0'
|
174
|
+
- !ruby/object:Gem::Dependency
|
175
|
+
name: benchmark-ips
|
176
|
+
requirement: !ruby/object:Gem::Requirement
|
177
|
+
none: false
|
178
|
+
requirements:
|
179
|
+
- - ! '>='
|
180
|
+
- !ruby/object:Gem::Version
|
181
|
+
version: '0'
|
182
|
+
type: :development
|
183
|
+
prerelease: false
|
184
|
+
version_requirements: !ruby/object:Gem::Requirement
|
185
|
+
none: false
|
186
|
+
requirements:
|
187
|
+
- - ! '>='
|
188
|
+
- !ruby/object:Gem::Version
|
189
|
+
version: '0'
|
190
|
+
- !ruby/object:Gem::Dependency
|
191
|
+
name: coveralls
|
192
|
+
requirement: !ruby/object:Gem::Requirement
|
193
|
+
none: false
|
194
|
+
requirements:
|
195
|
+
- - ! '>='
|
196
|
+
- !ruby/object:Gem::Version
|
197
|
+
version: '0'
|
198
|
+
type: :development
|
199
|
+
prerelease: false
|
200
|
+
version_requirements: !ruby/object:Gem::Requirement
|
201
|
+
none: false
|
202
|
+
requirements:
|
203
|
+
- - ! '>='
|
204
|
+
- !ruby/object:Gem::Version
|
205
|
+
version: '0'
|
206
|
+
description: Servies helps you to build a backend for your application.
|
207
|
+
email:
|
208
|
+
- marten@veldthuis.com
|
209
|
+
executables: []
|
210
|
+
extensions: []
|
211
|
+
extra_rdoc_files: []
|
212
|
+
files:
|
213
|
+
- lib/generators/servies/install_generator.rb
|
214
|
+
- lib/generators/servies/templates/backend/backend.rb
|
215
|
+
- lib/generators/servies/templates/backend/command.rb
|
216
|
+
- lib/generators/servies/templates/backend/interactor.rb
|
217
|
+
- lib/generators/servies/templates/backend/query.rb
|
218
|
+
- lib/servies.rb
|
219
|
+
- lib/servies/access_denied.rb
|
220
|
+
- lib/servies/backend.rb
|
221
|
+
- lib/servies/engine.rb
|
222
|
+
- lib/servies/operation.rb
|
223
|
+
- lib/servies/operation_finder.rb
|
224
|
+
- lib/servies/validation_error.rb
|
225
|
+
- lib/servies/validations.rb
|
226
|
+
- lib/servies/version.rb
|
227
|
+
homepage: https://github.com/marten/servies/
|
228
|
+
licenses: []
|
229
|
+
post_install_message:
|
230
|
+
rdoc_options: []
|
231
|
+
require_paths:
|
232
|
+
- lib
|
233
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
234
|
+
none: false
|
235
|
+
requirements:
|
236
|
+
- - ! '>='
|
237
|
+
- !ruby/object:Gem::Version
|
238
|
+
version: '0'
|
239
|
+
segments:
|
240
|
+
- 0
|
241
|
+
hash: -2216746290766598287
|
242
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
243
|
+
none: false
|
244
|
+
requirements:
|
245
|
+
- - ! '>='
|
246
|
+
- !ruby/object:Gem::Version
|
247
|
+
version: '0'
|
248
|
+
segments:
|
249
|
+
- 0
|
250
|
+
hash: -2216746290766598287
|
251
|
+
requirements: []
|
252
|
+
rubyforge_project:
|
253
|
+
rubygems_version: 1.8.23
|
254
|
+
signing_key:
|
255
|
+
specification_version: 3
|
256
|
+
summary: A service object framework for Ruby, with extra support for Rails.
|
257
|
+
test_files: []
|