appfuel 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.
Files changed (84) hide show
  1. checksums.yaml +7 -0
  2. data/.codeclimate.yml +25 -0
  3. data/.gitignore +10 -0
  4. data/.rspec +2 -0
  5. data/.rubocop.yml +1156 -0
  6. data/.travis.yml +19 -0
  7. data/CODE_OF_CONDUCT.md +74 -0
  8. data/Gemfile +9 -0
  9. data/README.md +38 -0
  10. data/Rakefile +6 -0
  11. data/appfuel.gemspec +42 -0
  12. data/bin/console +7 -0
  13. data/bin/setup +8 -0
  14. data/lib/appfuel.rb +210 -0
  15. data/lib/appfuel/application.rb +4 -0
  16. data/lib/appfuel/application/app_container.rb +223 -0
  17. data/lib/appfuel/application/container_class_registration.rb +22 -0
  18. data/lib/appfuel/application/container_key.rb +201 -0
  19. data/lib/appfuel/application/qualify_container_key.rb +76 -0
  20. data/lib/appfuel/application/root.rb +140 -0
  21. data/lib/appfuel/cli_msg_request.rb +19 -0
  22. data/lib/appfuel/configuration.rb +14 -0
  23. data/lib/appfuel/configuration/definition_dsl.rb +175 -0
  24. data/lib/appfuel/configuration/file_loader.rb +61 -0
  25. data/lib/appfuel/configuration/populate.rb +95 -0
  26. data/lib/appfuel/configuration/search.rb +45 -0
  27. data/lib/appfuel/db_model.rb +16 -0
  28. data/lib/appfuel/domain.rb +7 -0
  29. data/lib/appfuel/domain/criteria.rb +436 -0
  30. data/lib/appfuel/domain/domain_name_parser.rb +44 -0
  31. data/lib/appfuel/domain/dsl.rb +247 -0
  32. data/lib/appfuel/domain/entity.rb +242 -0
  33. data/lib/appfuel/domain/entity_collection.rb +87 -0
  34. data/lib/appfuel/domain/expr.rb +127 -0
  35. data/lib/appfuel/domain/value_object.rb +7 -0
  36. data/lib/appfuel/errors.rb +104 -0
  37. data/lib/appfuel/feature.rb +2 -0
  38. data/lib/appfuel/feature/action_loader.rb +25 -0
  39. data/lib/appfuel/feature/initializer.rb +43 -0
  40. data/lib/appfuel/handler.rb +6 -0
  41. data/lib/appfuel/handler/action.rb +17 -0
  42. data/lib/appfuel/handler/base.rb +103 -0
  43. data/lib/appfuel/handler/command.rb +18 -0
  44. data/lib/appfuel/handler/inject_dsl.rb +88 -0
  45. data/lib/appfuel/handler/validator_dsl.rb +256 -0
  46. data/lib/appfuel/initialize.rb +70 -0
  47. data/lib/appfuel/initialize/initializer.rb +68 -0
  48. data/lib/appfuel/msg_request.rb +207 -0
  49. data/lib/appfuel/predicates.rb +10 -0
  50. data/lib/appfuel/presenter.rb +18 -0
  51. data/lib/appfuel/presenter/base.rb +7 -0
  52. data/lib/appfuel/repository.rb +73 -0
  53. data/lib/appfuel/repository/base.rb +72 -0
  54. data/lib/appfuel/repository/initializer.rb +19 -0
  55. data/lib/appfuel/repository/mapper.rb +203 -0
  56. data/lib/appfuel/repository/mapping_dsl.rb +210 -0
  57. data/lib/appfuel/repository/mapping_entry.rb +76 -0
  58. data/lib/appfuel/repository/mapping_registry.rb +121 -0
  59. data/lib/appfuel/repository_runner.rb +60 -0
  60. data/lib/appfuel/request.rb +53 -0
  61. data/lib/appfuel/response.rb +96 -0
  62. data/lib/appfuel/response_handler.rb +79 -0
  63. data/lib/appfuel/root_module.rb +31 -0
  64. data/lib/appfuel/run_error.rb +9 -0
  65. data/lib/appfuel/storage.rb +3 -0
  66. data/lib/appfuel/storage/db.rb +4 -0
  67. data/lib/appfuel/storage/db/active_record_model.rb +42 -0
  68. data/lib/appfuel/storage/db/mapper.rb +213 -0
  69. data/lib/appfuel/storage/db/migration_initializer.rb +42 -0
  70. data/lib/appfuel/storage/db/migration_runner.rb +15 -0
  71. data/lib/appfuel/storage/db/migration_tasks.rb +18 -0
  72. data/lib/appfuel/storage/db/repository.rb +231 -0
  73. data/lib/appfuel/storage/db/repository_query.rb +13 -0
  74. data/lib/appfuel/storage/file.rb +1 -0
  75. data/lib/appfuel/storage/file/base.rb +32 -0
  76. data/lib/appfuel/storage/memory.rb +2 -0
  77. data/lib/appfuel/storage/memory/mapper.rb +30 -0
  78. data/lib/appfuel/storage/memory/repository.rb +37 -0
  79. data/lib/appfuel/types.rb +53 -0
  80. data/lib/appfuel/validation.rb +80 -0
  81. data/lib/appfuel/validation/validator.rb +59 -0
  82. data/lib/appfuel/validation/validator_pipe.rb +47 -0
  83. data/lib/appfuel/version.rb +3 -0
  84. metadata +335 -0
@@ -0,0 +1,80 @@
1
+ require_relative 'validation/validator'
2
+ require_relative 'validation/validator_pipe'
3
+
4
+ module Appfuel
5
+ module Validation
6
+ class << self
7
+ # Dsl used create and register validators in the app container. The key
8
+ # needs to be the fully qualified feature or global.
9
+ #
10
+ #
11
+ # @example define 'global.foo' do
12
+ # required(:test).filled(:str?)
13
+ # end
14
+ #
15
+ # this will add a validator in 'global.validators.foo'
16
+ #
17
+ # @example define 'auth.foo' do
18
+ # required(:test).filled(:str?)
19
+ # end
20
+ #
21
+ # this will add a validator in 'features.auth.validators.foo'
22
+ #
23
+ # @param key [String] qualified key to global or feature namespace
24
+ # @param opts [Hash] options
25
+ # @return Validator
26
+ def define(name, opts = {}, &block)
27
+ key, basename = build_validator_key(name)
28
+ container = Appfuel.app_container
29
+ validator = build_validator(basename, opts, &block)
30
+ container.register(key, validator)
31
+ end
32
+
33
+ # Turns the block of code given into a Dry::Validation schema or formi
34
+ # which is then used to create our validator.
35
+ #
36
+ # @param name [String] key used to register this validator in the container
37
+ # @param opts [Hash] options to configure validator
38
+ # @option type [String] form or schema for dry validation
39
+ # @option fail_fast [Bool] tells the system to fail right away
40
+ # @return Validator
41
+ def build_validator(name, opts = {}, &block)
42
+ fail_fast = opts[:fail_fast] == true ? true : false
43
+ schema_type = (opts.fetch(:type) { 'form' }).to_s.downcase
44
+
45
+ schema = create_dry_validator(schema_type, &block)
46
+ Validator.new(name, schema, fail_fast: fail_fast)
47
+ end
48
+
49
+ # Factory method create Dry::Validation::Schema or
50
+ # Dry::Validation::Schema::Form objects
51
+ #
52
+ # @param type [String] form or schema
53
+ def create_dry_validator(type, &block)
54
+ unless ['form', 'schema'].include?(type)
55
+ fail "validator type must 'form' or 'schema' (#{type}) given"
56
+ end
57
+
58
+ fail "block is required to build a validator" unless block_given?
59
+
60
+ method = type.capitalize
61
+ Dry::Validation.send(method, &block)
62
+ end
63
+ private
64
+
65
+ # Construct a full qualified namespace key to register a validator with.
66
+ # The basename of that key is used when creating the valdiator so it
67
+ # is returned with the key.
68
+ #
69
+ # @param name [String] partial namespace string of container key
70
+ # @return [Array] the fully qualified key and the basename
71
+ def build_validator_key(name)
72
+ key, *parts = name.to_s.split('.')
73
+ key = "features.#{key}" unless key == 'global'
74
+ ["#{key}.validators.#{parts.join('.')}", parts.last]
75
+ end
76
+
77
+ end
78
+ end
79
+ end
80
+
@@ -0,0 +1,59 @@
1
+ module Appfuel
2
+ module Validation
3
+ # Any validator that is run for an action or command will be created with
4
+ # this class. It service to abstract away Dry::Validation, the library we
5
+ # use from the system that runs all the validators. This allows us to use
6
+ # validators along side things like validator pipes without the system
7
+ # having to care.
8
+ class Validator
9
+ attr_reader :name, :schema
10
+
11
+ # @param name [String] used to register this validator in a container
12
+ # @param schema [Dry::Validation::Schema] the actual validator
13
+ # @param fail_fast [Bool] tell the system how to fail
14
+ # @return [Validator]
15
+ def initialize(name, schema, fail_fast: false)
16
+ @name = name
17
+ unless schema.respond_to?(:call)
18
+ fail ArgumentError, "schema must implement :call"
19
+ end
20
+ @schema = schema
21
+
22
+ fail_fast == true ? enable_fail_fast : disable_fail_fast
23
+ end
24
+
25
+ # Ensures the system will stop validating when this validator fails
26
+ #
27
+ # @return [Bool]
28
+ def enable_fail_fast
29
+ @fail_fast = true
30
+ end
31
+
32
+ # Ensures the system will continue validating when errors exist
33
+ #
34
+ # @return [Bool]
35
+ def disable_fail_fast
36
+ @fail_fast = false
37
+ end
38
+
39
+ # @return [Bool]
40
+ def fail_fast?
41
+ @fail_fast
42
+ end
43
+
44
+
45
+ # Delegate's to the Dry::Validation schema to validate the inputs
46
+ #
47
+ # @param inputs [Hash]
48
+ # @return [Dry::Validation::Result]
49
+ def call(inputs)
50
+ schema.call(inputs)
51
+ end
52
+
53
+ # Tell this system this is not a validation pipe
54
+ def pipe?
55
+ false
56
+ end
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,47 @@
1
+ module Appfuel
2
+ module Validation
3
+ # A pipe is just a lambda that take two arguments. It is designed to
4
+ # live between two validators in an array and maninuplate the output
5
+ # of the first validator to satisfy the secord. It is needed when
6
+ # you want to use two reusable validators that don't quite work
7
+ # togather.
8
+ class ValidatorPipe
9
+ attr_reader :name, :dependencies, :code
10
+
11
+ #
12
+ # @param name [String] key used for errors & containers
13
+ # @param dependencies [Hash] for dependency injection
14
+ # @return [ValidatorPipe]
15
+ def initialize(name, dependencies = {}, &block)
16
+ unless block_given?
17
+ fail ArgumentError, "block is required"
18
+ end
19
+
20
+ unless block.arity == 2
21
+ fail ArgumentError, "validator pipe block needs two params"
22
+ end
23
+
24
+ @name = name
25
+ @code = block
26
+ @dependencies = dependencies
27
+ end
28
+
29
+ # Because validator and pipe live togather in the same array. The
30
+ # system runner needs to be able to tell them apart.
31
+ #
32
+ # @return [TrueCase]
33
+ def pipe?
34
+ true
35
+ end
36
+
37
+ # Delegate call to the actual pipe lambda
38
+ #
39
+ # @param inputs [Hash]
40
+ # @param data [Dry::Container] dependency injection container
41
+ # @return [Hash] new inputs for the next validator
42
+ def call(inputs, data = Dry::Container.new)
43
+ code.call(inputs, data)
44
+ end
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,3 @@
1
+ module Appfuel
2
+ VERSION = "0.2.0"
3
+ end
metadata ADDED
@@ -0,0 +1,335 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: appfuel
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.2.0
5
+ platform: ruby
6
+ authors:
7
+ - Robert Scott-Buccleuch
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2017-05-09 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: activerecord
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: 5.0.2
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: 5.0.2
27
+ - !ruby/object:Gem::Dependency
28
+ name: dry-types
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - '='
32
+ - !ruby/object:Gem::Version
33
+ version: 0.9.2
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - '='
39
+ - !ruby/object:Gem::Version
40
+ version: 0.9.2
41
+ - !ruby/object:Gem::Dependency
42
+ name: dry-container
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '0.6'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '0.6'
55
+ - !ruby/object:Gem::Dependency
56
+ name: dry-validation
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: 0.10.5
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: 0.10.5
69
+ - !ruby/object:Gem::Dependency
70
+ name: dry-monads
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: '0.2'
76
+ type: :runtime
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: '0.2'
83
+ - !ruby/object:Gem::Dependency
84
+ name: dry-configurable
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: '0.6'
90
+ type: :runtime
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: '0.6'
97
+ - !ruby/object:Gem::Dependency
98
+ name: bundler
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - "~>"
102
+ - !ruby/object:Gem::Version
103
+ version: '1.13'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - "~>"
109
+ - !ruby/object:Gem::Version
110
+ version: '1.13'
111
+ - !ruby/object:Gem::Dependency
112
+ name: rake
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - "~>"
116
+ - !ruby/object:Gem::Version
117
+ version: '10.0'
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - "~>"
123
+ - !ruby/object:Gem::Version
124
+ version: '10.0'
125
+ - !ruby/object:Gem::Dependency
126
+ name: rspec
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - "~>"
130
+ - !ruby/object:Gem::Version
131
+ version: '3.5'
132
+ type: :development
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - "~>"
137
+ - !ruby/object:Gem::Version
138
+ version: '3.5'
139
+ - !ruby/object:Gem::Dependency
140
+ name: pry
141
+ requirement: !ruby/object:Gem::Requirement
142
+ requirements:
143
+ - - "~>"
144
+ - !ruby/object:Gem::Version
145
+ version: '0.10'
146
+ type: :development
147
+ prerelease: false
148
+ version_requirements: !ruby/object:Gem::Requirement
149
+ requirements:
150
+ - - "~>"
151
+ - !ruby/object:Gem::Version
152
+ version: '0.10'
153
+ - !ruby/object:Gem::Dependency
154
+ name: awesome_print
155
+ requirement: !ruby/object:Gem::Requirement
156
+ requirements:
157
+ - - "~>"
158
+ - !ruby/object:Gem::Version
159
+ version: '1.7'
160
+ type: :development
161
+ prerelease: false
162
+ version_requirements: !ruby/object:Gem::Requirement
163
+ requirements:
164
+ - - "~>"
165
+ - !ruby/object:Gem::Version
166
+ version: '1.7'
167
+ - !ruby/object:Gem::Dependency
168
+ name: pry-awesome_print
169
+ requirement: !ruby/object:Gem::Requirement
170
+ requirements:
171
+ - - ">="
172
+ - !ruby/object:Gem::Version
173
+ version: 9.6.1
174
+ type: :development
175
+ prerelease: false
176
+ version_requirements: !ruby/object:Gem::Requirement
177
+ requirements:
178
+ - - ">="
179
+ - !ruby/object:Gem::Version
180
+ version: 9.6.1
181
+ - !ruby/object:Gem::Dependency
182
+ name: database_cleaner
183
+ requirement: !ruby/object:Gem::Requirement
184
+ requirements:
185
+ - - "~>"
186
+ - !ruby/object:Gem::Version
187
+ version: '1.5'
188
+ type: :development
189
+ prerelease: false
190
+ version_requirements: !ruby/object:Gem::Requirement
191
+ requirements:
192
+ - - "~>"
193
+ - !ruby/object:Gem::Version
194
+ version: '1.5'
195
+ - !ruby/object:Gem::Dependency
196
+ name: faker
197
+ requirement: !ruby/object:Gem::Requirement
198
+ requirements:
199
+ - - "~>"
200
+ - !ruby/object:Gem::Version
201
+ version: '1.7'
202
+ type: :development
203
+ prerelease: false
204
+ version_requirements: !ruby/object:Gem::Requirement
205
+ requirements:
206
+ - - "~>"
207
+ - !ruby/object:Gem::Version
208
+ version: '1.7'
209
+ - !ruby/object:Gem::Dependency
210
+ name: factory_girl
211
+ requirement: !ruby/object:Gem::Requirement
212
+ requirements:
213
+ - - "~>"
214
+ - !ruby/object:Gem::Version
215
+ version: '4.8'
216
+ type: :development
217
+ prerelease: false
218
+ version_requirements: !ruby/object:Gem::Requirement
219
+ requirements:
220
+ - - "~>"
221
+ - !ruby/object:Gem::Version
222
+ version: '4.8'
223
+ description: A library that allows you to isolate your business code
224
+ email:
225
+ - rsb.code@gmail.com
226
+ executables: []
227
+ extensions: []
228
+ extra_rdoc_files: []
229
+ files:
230
+ - ".codeclimate.yml"
231
+ - ".gitignore"
232
+ - ".rspec"
233
+ - ".rubocop.yml"
234
+ - ".travis.yml"
235
+ - CODE_OF_CONDUCT.md
236
+ - Gemfile
237
+ - README.md
238
+ - Rakefile
239
+ - appfuel.gemspec
240
+ - bin/console
241
+ - bin/setup
242
+ - lib/appfuel.rb
243
+ - lib/appfuel/application.rb
244
+ - lib/appfuel/application/app_container.rb
245
+ - lib/appfuel/application/container_class_registration.rb
246
+ - lib/appfuel/application/container_key.rb
247
+ - lib/appfuel/application/qualify_container_key.rb
248
+ - lib/appfuel/application/root.rb
249
+ - lib/appfuel/cli_msg_request.rb
250
+ - lib/appfuel/configuration.rb
251
+ - lib/appfuel/configuration/definition_dsl.rb
252
+ - lib/appfuel/configuration/file_loader.rb
253
+ - lib/appfuel/configuration/populate.rb
254
+ - lib/appfuel/configuration/search.rb
255
+ - lib/appfuel/db_model.rb
256
+ - lib/appfuel/domain.rb
257
+ - lib/appfuel/domain/criteria.rb
258
+ - lib/appfuel/domain/domain_name_parser.rb
259
+ - lib/appfuel/domain/dsl.rb
260
+ - lib/appfuel/domain/entity.rb
261
+ - lib/appfuel/domain/entity_collection.rb
262
+ - lib/appfuel/domain/expr.rb
263
+ - lib/appfuel/domain/value_object.rb
264
+ - lib/appfuel/errors.rb
265
+ - lib/appfuel/feature.rb
266
+ - lib/appfuel/feature/action_loader.rb
267
+ - lib/appfuel/feature/initializer.rb
268
+ - lib/appfuel/handler.rb
269
+ - lib/appfuel/handler/action.rb
270
+ - lib/appfuel/handler/base.rb
271
+ - lib/appfuel/handler/command.rb
272
+ - lib/appfuel/handler/inject_dsl.rb
273
+ - lib/appfuel/handler/validator_dsl.rb
274
+ - lib/appfuel/initialize.rb
275
+ - lib/appfuel/initialize/initializer.rb
276
+ - lib/appfuel/msg_request.rb
277
+ - lib/appfuel/predicates.rb
278
+ - lib/appfuel/presenter.rb
279
+ - lib/appfuel/presenter/base.rb
280
+ - lib/appfuel/repository.rb
281
+ - lib/appfuel/repository/base.rb
282
+ - lib/appfuel/repository/initializer.rb
283
+ - lib/appfuel/repository/mapper.rb
284
+ - lib/appfuel/repository/mapping_dsl.rb
285
+ - lib/appfuel/repository/mapping_entry.rb
286
+ - lib/appfuel/repository/mapping_registry.rb
287
+ - lib/appfuel/repository_runner.rb
288
+ - lib/appfuel/request.rb
289
+ - lib/appfuel/response.rb
290
+ - lib/appfuel/response_handler.rb
291
+ - lib/appfuel/root_module.rb
292
+ - lib/appfuel/run_error.rb
293
+ - lib/appfuel/storage.rb
294
+ - lib/appfuel/storage/db.rb
295
+ - lib/appfuel/storage/db/active_record_model.rb
296
+ - lib/appfuel/storage/db/mapper.rb
297
+ - lib/appfuel/storage/db/migration_initializer.rb
298
+ - lib/appfuel/storage/db/migration_runner.rb
299
+ - lib/appfuel/storage/db/migration_tasks.rb
300
+ - lib/appfuel/storage/db/repository.rb
301
+ - lib/appfuel/storage/db/repository_query.rb
302
+ - lib/appfuel/storage/file.rb
303
+ - lib/appfuel/storage/file/base.rb
304
+ - lib/appfuel/storage/memory.rb
305
+ - lib/appfuel/storage/memory/mapper.rb
306
+ - lib/appfuel/storage/memory/repository.rb
307
+ - lib/appfuel/types.rb
308
+ - lib/appfuel/validation.rb
309
+ - lib/appfuel/validation/validator.rb
310
+ - lib/appfuel/validation/validator_pipe.rb
311
+ - lib/appfuel/version.rb
312
+ homepage: https://github.com/rsb/appfuel
313
+ licenses: []
314
+ metadata: {}
315
+ post_install_message:
316
+ rdoc_options: []
317
+ require_paths:
318
+ - lib
319
+ required_ruby_version: !ruby/object:Gem::Requirement
320
+ requirements:
321
+ - - ">="
322
+ - !ruby/object:Gem::Version
323
+ version: '0'
324
+ required_rubygems_version: !ruby/object:Gem::Requirement
325
+ requirements:
326
+ - - ">="
327
+ - !ruby/object:Gem::Version
328
+ version: '0'
329
+ requirements: []
330
+ rubyforge_project:
331
+ rubygems_version: 2.5.2
332
+ signing_key:
333
+ specification_version: 4
334
+ summary: Appfuel decouples your business code from its API framework
335
+ test_files: []