smooth 2.0.1 → 2.0.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +7 -0
- data/Gemfile +1 -2
- data/README.md +150 -5
- data/Rakefile +16 -0
- data/app/assets/javascripts/smooth/index.js +5152 -0
- data/bin/smooth +9 -0
- data/{app/assets/javascripts/smooth → developer-tools}/.keep +0 -0
- data/developer-tools/bower.json +8 -0
- data/developer-tools/config.ru +3 -0
- data/developer-tools/dist/08d606864d3ad3f0b98660d391f5a1c2.gif +0 -0
- data/developer-tools/dist/2d66bcdc27cd89f71068e98a7a929712.gif +0 -0
- data/developer-tools/dist/3e9816417b11485d454f9b3662b06e7b.eot +0 -0
- data/developer-tools/dist/47de617fd1d745ad120ccb9e2924b98c.gif +0 -0
- data/developer-tools/dist/5ae23ad29b67289a1375d2043e289c52.eot +0 -0
- data/developer-tools/dist/60c2a8500e63bf211b7df9608f7613ea.svg +450 -0
- data/developer-tools/dist/645f50ba6c1e56f078fa018855d97eb0.gif +0 -0
- data/developer-tools/dist/71ab514d1cedda303417ad7a06472fea.ttf +0 -0
- data/developer-tools/dist/8cca2f02b0af2da365ff4d1755f29146.ttf +0 -0
- data/developer-tools/dist/939cf252f0eb4efbd2d170c974411c49.gif +0 -0
- data/developer-tools/dist/9af25aaeb6ca6d08d213b04841813eb5.gif +0 -0
- data/developer-tools/dist/b683029bafe0305ac2234038a03e1541.woff +0 -0
- data/developer-tools/dist/c9dec22105ad9330c811599b8b6464f8.woff +0 -0
- data/developer-tools/dist/ca279c55a51ab2641c4712a333633581.gif +0 -0
- data/developer-tools/dist/client.js +5152 -0
- data/developer-tools/dist/f5b27137d3f5e9b1d91b16b37386dd03.gif +0 -0
- data/developer-tools/dist/f99a231ed57ee113b50b1c3e9f9fcdc3.svg +399 -0
- data/developer-tools/dist/index.html +18 -0
- data/developer-tools/dist/inspector.js +38432 -0
- data/developer-tools/dist/jquery.min.js +9190 -0
- data/developer-tools/package.json +39 -0
- data/developer-tools/server.js +14 -0
- data/developer-tools/src/client.coffee +21 -0
- data/developer-tools/src/client/collection.coffee +14 -0
- data/developer-tools/src/client/model.coffee +11 -0
- data/developer-tools/src/client/resource.coffee +132 -0
- data/{app/controllers/.keep → developer-tools/src/client/runner.coffee} +0 -0
- data/developer-tools/src/dependencies.coffee +7 -0
- data/developer-tools/src/inspector.cjsx +49 -0
- data/developer-tools/src/inspector/models/interface_collection.coffee +31 -0
- data/developer-tools/src/inspector/pages/index.cjsx +31 -0
- data/developer-tools/src/inspector/pages/resources.cjsx +5 -0
- data/developer-tools/src/inspector/views/grid_sort.cjsx +23 -0
- data/developer-tools/src/inspector/views/icon_heading.cjsx +15 -0
- data/developer-tools/src/inspector/views/resource_card.cjsx +34 -0
- data/developer-tools/src/inspector/views/sidebar.cjsx +12 -0
- data/developer-tools/src/inspector/views/toolbar.cjsx +17 -0
- data/developer-tools/src/styles/index.scss +136 -0
- data/developer-tools/src/styles/views.scss +13 -0
- data/developer-tools/src/util.coffee +48 -0
- data/developer-tools/webpack.config.js +56 -0
- data/developer-tools/webpack.hot.config.js +65 -0
- data/lib/smooth.rb +209 -28
- data/lib/smooth/active_record/adapter.rb +24 -0
- data/lib/smooth/api.rb +272 -18
- data/lib/smooth/api/policy.rb +2 -2
- data/lib/smooth/api/tracking.rb +4 -4
- data/lib/smooth/application.rb +66 -0
- data/lib/smooth/cache.rb +1 -1
- data/lib/smooth/command.rb +267 -18
- data/lib/smooth/command/async_worker.rb +27 -0
- data/lib/smooth/command/instrumented.rb +6 -4
- data/lib/smooth/command/run_proxy.rb +21 -0
- data/lib/smooth/configuration.rb +63 -8
- data/lib/smooth/documentation.rb +3 -6
- data/lib/smooth/dsl.rb +1 -36
- data/lib/smooth/dsl_adapter.rb +34 -0
- data/lib/smooth/event.rb +8 -4
- data/lib/smooth/event/proxy.rb +9 -0
- data/lib/smooth/event/relay.rb +38 -0
- data/lib/smooth/example.rb +1 -1
- data/lib/smooth/ext/core.rb +16 -0
- data/lib/smooth/model_adapter.rb +31 -0
- data/lib/smooth/query.rb +143 -13
- data/lib/smooth/resource.rb +227 -52
- data/lib/smooth/resource/router.rb +217 -0
- data/lib/smooth/resource/templating.rb +62 -0
- data/lib/smooth/resource/tracking.rb +1 -1
- data/lib/smooth/response.rb +73 -0
- data/lib/smooth/serializer.rb +102 -11
- data/lib/smooth/user_adapter.rb +83 -0
- data/lib/smooth/util.rb +17 -0
- data/lib/smooth/version.rb +1 -1
- data/smooth.gemspec +6 -2
- data/spec/acceptance/books_routes_spec.rb +50 -0
- data/spec/acceptance/embedded_relationships_spec.rb +26 -0
- data/spec/dummy/app/apis/application_api.rb +8 -3
- data/spec/dummy/app/commands/create_book.rb +5 -0
- data/spec/dummy/app/models/book.rb +1 -0
- data/spec/dummy/app/models/library.rb +2 -0
- data/spec/dummy/app/models/user.rb +2 -0
- data/spec/dummy/app/queries/book_query.rb +13 -0
- data/spec/dummy/app/resources/{books.rb → books_definition.rb} +37 -12
- data/spec/dummy/db/migrate/20140824215902_create_users.rb +10 -0
- data/spec/dummy/db/migrate/20140826193259_create_libraries.rb +10 -0
- data/spec/dummy/db/schema.rb +8 -1
- data/spec/lib/smooth/api/async_spec.rb +21 -0
- data/spec/lib/smooth/api_spec.rb +8 -0
- data/spec/lib/smooth/command_spec.rb +87 -6
- data/spec/lib/smooth/configuration_spec.rb +4 -0
- data/spec/lib/smooth/event/relay_spec.rb +33 -0
- data/spec/lib/smooth/event_spec.rb +5 -8
- data/spec/lib/smooth/query_spec.rb +42 -0
- data/spec/lib/smooth/resource/router_spec.rb +14 -0
- data/spec/lib/smooth/resource_spec.rb +33 -1
- data/spec/lib/smooth/serializer_spec.rb +20 -0
- data/spec/lib/smooth/templating_spec.rb +23 -0
- data/spec/lib/smooth/util_spec.rb +22 -0
- data/spec/spec_helper.rb +1 -1
- metadata +151 -17
- data/app/helpers/.keep +0 -0
- data/app/mailers/.keep +0 -0
- data/app/models/.keep +0 -0
- data/app/views/.keep +0 -0
- data/spec/dummy/db/development.sqlite3 +0 -0
- data/spec/dummy/db/test.sqlite3 +0 -0
data/lib/smooth/cache.rb
CHANGED
data/lib/smooth/command.rb
CHANGED
@@ -1,35 +1,131 @@
|
|
1
|
-
require 'smooth/ext/mutations'
|
2
|
-
require 'smooth/command/instrumented'
|
3
|
-
|
4
1
|
class Smooth::Command < Mutations::Command
|
5
2
|
include Instrumented
|
6
3
|
|
4
|
+
def self.as(current_user)
|
5
|
+
require 'smooth/command/run_proxy' unless defined?(RunProxy)
|
6
|
+
RunProxy.new(current_user, self)
|
7
|
+
end
|
8
|
+
|
9
|
+
# DSL Improvements English
|
10
|
+
def self.params(*args, &block)
|
11
|
+
send(:required, *args, &block)
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.interface(*args, &block)
|
15
|
+
send(:required, *args, &block)
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.input_argument_names
|
19
|
+
required_inputs.keys + optional_inputs.keys
|
20
|
+
end
|
21
|
+
|
22
|
+
# Commands are aware of who is running them
|
23
|
+
attr_accessor :current_user
|
24
|
+
|
7
25
|
class_attribute :resource_name,
|
8
26
|
:command_action,
|
9
|
-
:event_namespace
|
27
|
+
:event_namespace,
|
28
|
+
:model_class,
|
29
|
+
:base_scope,
|
30
|
+
:parent_resource
|
10
31
|
|
11
|
-
def self.
|
12
|
-
|
32
|
+
def self.base_scope
|
33
|
+
@base_scope || :all
|
13
34
|
end
|
14
35
|
|
15
|
-
def
|
16
|
-
|
36
|
+
def parent_api
|
37
|
+
self.class.parent_api
|
38
|
+
end
|
39
|
+
|
40
|
+
def parent_resource
|
41
|
+
self.class.parent_resource
|
42
|
+
end
|
43
|
+
|
44
|
+
def self.belongs_to_resource(resource)
|
45
|
+
self.parent_resource = resource
|
46
|
+
end
|
47
|
+
|
48
|
+
def self.parent_api
|
49
|
+
parent_resource.api
|
50
|
+
end
|
51
|
+
|
52
|
+
# Returns the model scope for this command. If a scope method
|
53
|
+
# is set on this command, it will make sure to scope the model
|
54
|
+
# by that method. It will pass whatever arguments you pass to scope
|
55
|
+
# to the scope method. if you pass no args, and the scope requires one,
|
56
|
+
# we will assume the user wants us to pass the current user of the command
|
57
|
+
def scope(*args)
|
58
|
+
@scope ||= begin
|
59
|
+
meth = model_class.send(:method, self.class.base_scope)
|
60
|
+
|
61
|
+
if meth.arity.abs >= 1
|
62
|
+
args.push(current_user) if args.empty?
|
63
|
+
model_class.send(self.class.base_scope, *args)
|
64
|
+
else
|
65
|
+
model_class.send(self.class.base_scope)
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
def scope=(new_scope)
|
71
|
+
@scope = new_scope || scope
|
72
|
+
end
|
73
|
+
|
74
|
+
def self.scope(setting = nil)
|
75
|
+
self.base_scope = setting if setting
|
76
|
+
base_scope || :all
|
17
77
|
end
|
18
78
|
|
19
79
|
def self.event_namespace
|
20
|
-
@event_namespace || "#{ command_action }.#{
|
80
|
+
@event_namespace || "#{ command_action }.#{ resource_alias }".downcase
|
21
81
|
end
|
22
82
|
|
23
|
-
def
|
83
|
+
def self.resource_alias
|
84
|
+
resource_name.singularize.underscore
|
85
|
+
end
|
86
|
+
|
87
|
+
def self.resource_name
|
88
|
+
value = @resource_name.to_s
|
89
|
+
|
90
|
+
if value.empty? && model_class
|
91
|
+
value = model_class.to_s
|
92
|
+
end
|
93
|
+
|
94
|
+
value
|
95
|
+
end
|
96
|
+
|
97
|
+
def self.object_path
|
98
|
+
resource_name.downcase + '.' + command_action
|
99
|
+
end
|
100
|
+
|
101
|
+
def event_namespace
|
102
|
+
self.class.event_namespace
|
103
|
+
end
|
104
|
+
|
105
|
+
def object_path
|
106
|
+
self.class.object_path
|
107
|
+
end
|
108
|
+
|
109
|
+
def resource_name
|
110
|
+
self.class.resource_name
|
111
|
+
end
|
112
|
+
|
113
|
+
def resource_alias
|
114
|
+
self.class.resource_alias
|
115
|
+
end
|
116
|
+
|
117
|
+
def model_class
|
118
|
+
self.class.model_class
|
119
|
+
end
|
24
120
|
|
25
121
|
# DSL Hooks
|
26
122
|
#
|
27
123
|
#
|
28
|
-
def self.configure
|
124
|
+
def self.configure(dsl_config_object, resource = nil)
|
29
125
|
resource ||= Smooth.current_resource
|
30
|
-
klass = define_or_open(
|
126
|
+
klass = define_or_open(dsl_config_object, resource)
|
31
127
|
|
32
|
-
Array(
|
128
|
+
Array(dsl_config_object.blocks).each do |blk|
|
33
129
|
klass.class_eval(&blk)
|
34
130
|
end
|
35
131
|
|
@@ -41,15 +137,168 @@ class Smooth::Command < Mutations::Command
|
|
41
137
|
base = Smooth.command
|
42
138
|
|
43
139
|
name = options.name.to_s.camelize
|
44
|
-
klass = "#{ name }#{
|
140
|
+
klass = "#{ name }#{ resource.model_class }".gsub(/\s+/, '')
|
141
|
+
|
142
|
+
apply_options = lambda do |k|
|
143
|
+
k.model_class ||= resource.model_class if resource.model_class
|
144
|
+
|
145
|
+
k.belongs_to_resource(resource)
|
146
|
+
|
147
|
+
k.resource_name = resource.name.to_s
|
148
|
+
k.command_action = options.name.to_s
|
149
|
+
end
|
45
150
|
|
46
151
|
if command_klass = Object.const_get(klass) rescue nil
|
47
|
-
return command_klass
|
152
|
+
return command_klass.tap(&apply_options)
|
48
153
|
end
|
49
154
|
|
50
|
-
|
51
|
-
|
52
|
-
|
155
|
+
parent_klass = Class.new(base)
|
156
|
+
|
157
|
+
begin
|
158
|
+
Object.const_set(klass, parent_klass).tap(&apply_options)
|
159
|
+
rescue => ex
|
160
|
+
puts ex.message
|
161
|
+
puts "Error setting #{ klass } #{ base }. klass is a #{ klass.class }"
|
162
|
+
end
|
163
|
+
|
164
|
+
parent_klass
|
165
|
+
end
|
166
|
+
|
167
|
+
# Interface Documentation
|
168
|
+
#
|
169
|
+
def interface_for(filter)
|
170
|
+
self.class.interface_description.filters.send(filter)
|
171
|
+
end
|
172
|
+
|
173
|
+
def self.interface_description
|
174
|
+
interface_documentation
|
175
|
+
end
|
176
|
+
|
177
|
+
def self.interface_documentation
|
178
|
+
optional_inputs = input_filters.optional_inputs
|
179
|
+
required_inputs = input_filters.required_inputs
|
180
|
+
|
181
|
+
data = {
|
182
|
+
required: required_inputs.keys,
|
183
|
+
optional: optional_inputs.keys,
|
184
|
+
filters: {}
|
185
|
+
}
|
186
|
+
|
187
|
+
blk = lambda do |memo, parts, required|
|
188
|
+
key, filter = parts
|
189
|
+
|
190
|
+
type = filter.class.name[/^Mutations::([a-zA-Z]*)Filter$/, 1].underscore
|
191
|
+
options = filter.options.merge(required: required)
|
192
|
+
|
193
|
+
value = memo[key] = {
|
194
|
+
type: type,
|
195
|
+
options: options.reject { |_k, v| v.nil? },
|
196
|
+
description: input_descriptions[key]
|
197
|
+
}
|
198
|
+
|
199
|
+
if options[:faker]
|
200
|
+
value[:example] = Smooth.faker(options[:faker])
|
201
|
+
end
|
202
|
+
|
203
|
+
memo
|
204
|
+
end
|
205
|
+
|
206
|
+
required_inputs.reduce(data[:filters]) do |memo, parts|
|
207
|
+
blk.call(memo, parts, true)
|
208
|
+
end
|
209
|
+
|
210
|
+
optional_inputs.reduce(data[:filters]) do |memo, parts|
|
211
|
+
blk.call(memo, parts, false)
|
212
|
+
end
|
213
|
+
|
214
|
+
data.to_mash
|
215
|
+
end
|
216
|
+
|
217
|
+
def self.filter_for_param(param)
|
218
|
+
optional_inputs[param] || required_inputs[param]
|
219
|
+
end
|
220
|
+
|
221
|
+
def self.filter_options_for_param(param)
|
222
|
+
filter_for_param(param).try(:options)
|
223
|
+
end
|
224
|
+
|
225
|
+
def self.response_class
|
226
|
+
Smooth::Response
|
227
|
+
end
|
228
|
+
|
229
|
+
# Creates a new instance of the Smooth::Command::Response
|
230
|
+
# class in response to a request from the Router. It is
|
231
|
+
# assumed that a request object responds to: user, and params
|
232
|
+
def self.respond_to_request(request_object, options = {})
|
233
|
+
klass = self
|
234
|
+
|
235
|
+
outcome = options.fetch(:outcome) do
|
236
|
+
klass.as(request_object.user).run(request_object.params)
|
237
|
+
end
|
238
|
+
|
239
|
+
response_class.new(outcome, serializer_options).tap do |response|
|
240
|
+
response.request_headers = request_object.headers
|
241
|
+
response.serializer = find_serializer_for(request_object)
|
242
|
+
response.event_namespace = event_namespace
|
243
|
+
response.command_action = command_action
|
244
|
+
response.current_user = request_object.user
|
245
|
+
end
|
246
|
+
end
|
247
|
+
|
248
|
+
def self.find_serializer_for(_request_object)
|
249
|
+
resource = Smooth.resource(resource_name)
|
250
|
+
resource ||= Smooth.resource("#{ resource_name }".pluralize)
|
251
|
+
|
252
|
+
# TODO
|
253
|
+
# We can make the preferred format something you can
|
254
|
+
# specify via a header or parameter. We can also restrict
|
255
|
+
# certain serializers from certain policies.
|
256
|
+
preferred_format = :default
|
257
|
+
|
258
|
+
resource.fetch(:serializer, preferred_format)
|
259
|
+
end
|
260
|
+
|
261
|
+
def self.serializer_options
|
262
|
+
{}
|
263
|
+
end
|
264
|
+
|
265
|
+
# Allows for defining common execution pattern methods
|
266
|
+
# mostly for standard CRUD against scoped models
|
267
|
+
def self.execute(execution_pattern = nil, &block)
|
268
|
+
send :define_method, :execute, (block || get_execution_pattern(execution_pattern))
|
269
|
+
end
|
270
|
+
|
271
|
+
Patterns = {}
|
272
|
+
|
273
|
+
Patterns[:update] = lambda do
|
274
|
+
scoped_find_object.update_attributes(inputs)
|
275
|
+
scoped_find_object
|
276
|
+
end
|
277
|
+
|
278
|
+
Patterns[:create] = lambda do
|
279
|
+
scope.create(inputs)
|
280
|
+
end
|
281
|
+
|
282
|
+
Patterns[:destroy] = lambda do
|
283
|
+
scoped_find_object.destroy
|
284
|
+
scoped_find_object
|
285
|
+
end
|
286
|
+
|
287
|
+
def scoped_find_object
|
288
|
+
@scoped_find ||= if scope.respond_to?(:find) && found = (scope.find(id) rescue nil)
|
289
|
+
found
|
290
|
+
else
|
291
|
+
add_error(:id, :not_found, "could not find a #{ resource_name } model with that id")
|
292
|
+
end
|
293
|
+
end
|
294
|
+
|
295
|
+
def self.get_execution_pattern(pattern_name)
|
296
|
+
if respond_to?("#{ pattern_name }_execution_pattern")
|
297
|
+
return method("#{ pattern_name }_execution_pattern").to_proc
|
298
|
+
elsif Patterns.key?(pattern_name.to_sym)
|
299
|
+
Patterns.fetch(pattern_name.to_sym)
|
300
|
+
else
|
301
|
+
return method(:execute).to_proc
|
53
302
|
end
|
54
303
|
end
|
55
304
|
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module Smooth
|
2
|
+
class Command::AsyncWorker
|
3
|
+
unless Smooth.config.async_provider
|
4
|
+
fail 'Must specify an async provider. e.g. Sidekiq::Worker on Smooth.config.async_provider'
|
5
|
+
end
|
6
|
+
|
7
|
+
def self.options(*args)
|
8
|
+
send(:sidekiq_options, *args) if defined?(Sidekiq)
|
9
|
+
end
|
10
|
+
|
11
|
+
def perform(serialized_payload)
|
12
|
+
if hash = memory_store.read(serialized_payload)
|
13
|
+
api, object_path, payload = hash.values_at('api', 'object_path', 'payload')
|
14
|
+
current_user = payload['current_user'] || hash['current_user']
|
15
|
+
|
16
|
+
chain = Smooth(api).lookup_object_by(object_path)
|
17
|
+
chain = chain.as(current_user) if current_user
|
18
|
+
|
19
|
+
chain.run(payload)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def memory_store
|
24
|
+
Smooth.config.memory_store
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -29,15 +29,17 @@ module Smooth
|
|
29
29
|
end
|
30
30
|
end
|
31
31
|
|
32
|
-
def run_with_instrumentation
|
32
|
+
def run_with_instrumentation(event_prefix = nil)
|
33
33
|
outcome = run_with_outcome
|
34
34
|
|
35
|
+
event_prefix = "#{ event_prefix }." if event_prefix
|
36
|
+
|
35
37
|
if outcome.success?
|
36
38
|
result = outcome.result
|
37
|
-
track_event("#{ event_namespace }", result: result, inputs: inputs)
|
38
|
-
|
39
|
+
track_event("#{ event_prefix }#{ event_namespace }", result: result, inputs: inputs, current_user: current_user)
|
40
|
+
outcome
|
39
41
|
else
|
40
|
-
track_event("errors/#{ event_namespace }", errors: outcome.errors, inputs: inputs)
|
42
|
+
track_event("errors/#{ event_prefix }#{ event_namespace }", errors: outcome.errors, inputs: inputs, current_user: current_user)
|
41
43
|
outcome
|
42
44
|
end
|
43
45
|
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# Internal class to provide current user awareness to the
|
2
|
+
module Smooth
|
3
|
+
class Command < Mutations::Command
|
4
|
+
class RunProxy
|
5
|
+
attr_accessor :current_user, :cmd
|
6
|
+
|
7
|
+
def initialize(current_user, cmd)
|
8
|
+
@current_user = current_user
|
9
|
+
@cmd = cmd
|
10
|
+
end
|
11
|
+
|
12
|
+
def run!(*args)
|
13
|
+
cmd.new(*args).tap { |c| c.current_user = current_user }.run!
|
14
|
+
end
|
15
|
+
|
16
|
+
def run(*args)
|
17
|
+
cmd.new(*args).tap { |c| c.current_user = current_user }.run
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
data/lib/smooth/configuration.rb
CHANGED
@@ -1,5 +1,3 @@
|
|
1
|
-
require 'singleton'
|
2
|
-
|
3
1
|
module Smooth
|
4
2
|
class Configuration
|
5
3
|
include Singleton
|
@@ -7,18 +5,75 @@ module Smooth
|
|
7
5
|
cattr_accessor :query_class,
|
8
6
|
:command_class,
|
9
7
|
:serializer_class,
|
10
|
-
:
|
8
|
+
:object_path_separator,
|
9
|
+
:enable_events,
|
10
|
+
:definition_folders,
|
11
|
+
:eager_load_app_folders,
|
12
|
+
:active_record_config,
|
13
|
+
:models_path,
|
14
|
+
:schema_file,
|
15
|
+
:migrations_path,
|
16
|
+
:root,
|
17
|
+
:include_root_in_json,
|
18
|
+
:auth_token_column,
|
19
|
+
:enable_factories,
|
20
|
+
:async_provider,
|
21
|
+
:memory_store,
|
22
|
+
:embed_relationships_as
|
23
|
+
|
24
|
+
@@query_class = Smooth::Query
|
25
|
+
@@command_class = Smooth::Command
|
26
|
+
@@serializer_class = defined?(ApplicationSerializer) ? ApplicationSerializer : Smooth::Serializer
|
27
|
+
@@enable_events = true
|
28
|
+
@@eager_load_app_folders = true
|
29
|
+
@@models_path = 'app/models'
|
30
|
+
@@object_path_separator = '.'
|
31
|
+
@@definition_folders = %w(app/models app/apis app/queries app/commands app/serializers app/resources)
|
32
|
+
@@include_root_in_json = true
|
33
|
+
@@enable_factories = true
|
11
34
|
|
12
|
-
@@
|
13
|
-
@@
|
14
|
-
@@
|
15
|
-
@@
|
35
|
+
@@active_record_config = 'config/database.yml'
|
36
|
+
@@schema_file = 'db/schema.rb'
|
37
|
+
@@migrations_path = 'db/migrate'
|
38
|
+
@@root = Dir.pwd
|
39
|
+
@@auth_token_column = :authentication_token
|
40
|
+
@@async_provider = Sidekiq::Worker if defined?(Sidekiq)
|
41
|
+
@@memory_store = Smooth.cache
|
42
|
+
|
43
|
+
@@embed_relationships_as = :ids
|
44
|
+
|
45
|
+
def active_record
|
46
|
+
return active_record_config if active_record_config.is_a?(Hash)
|
47
|
+
file = root.join(active_record_config)
|
48
|
+
fail 'The config file does not exist at ' + file.to_s unless file.exist?
|
49
|
+
YAML.load(file.open).fetch(Smooth.env)
|
50
|
+
end
|
16
51
|
|
17
52
|
def enable_event_tracking?
|
18
53
|
!!@@enable_events
|
19
54
|
end
|
20
55
|
|
21
|
-
def
|
56
|
+
def root
|
57
|
+
Pathname(@@root)
|
58
|
+
end
|
59
|
+
|
60
|
+
def app_folder_paths
|
61
|
+
Array(definition_folders).map { |f| root.join(f) }
|
62
|
+
end
|
63
|
+
|
64
|
+
def models_path
|
65
|
+
root.join(@@models_path)
|
66
|
+
end
|
67
|
+
|
68
|
+
def method_missing(meth, *args, &block)
|
69
|
+
if meth.to_s.match(/(\w+)\?$/)
|
70
|
+
!!(send(Regexp.last_match[1], *args, &block)) if respond_to?(Regexp.last_match[1])
|
71
|
+
else
|
72
|
+
super
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
def self.method_missing(meth, *args, &block)
|
22
77
|
instance.send(meth, *args, &block)
|
23
78
|
end
|
24
79
|
end
|