ant-nanoservice 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: c65f35064474a60008d08715ee5572effd35423b44aca9b660a08896d9a99996
4
+ data.tar.gz: 977e04fe13bc73d2e6c3ed24ef43a9f7d132329519d21bb22294d8fbd39b62d4
5
+ SHA512:
6
+ metadata.gz: c042da4d28215444ac28d4003574c7f4693a6f088beba77a30c7576fa942370706d016e2efe2b3a18cc2331626e40ef58f202919cb24e263e5ebfa2e9ee89e83
7
+ data.tar.gz: da97707f967d3446cf3b805882f5c64ef81ee1ec1ccde5ed7c837d54997f8f70fe9cd099d240a1e66cdaaa726624e1b104c603a5cc1d79a1ac1885814a2a287a
@@ -0,0 +1,3 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'ant/server/format'
@@ -0,0 +1,3 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'nanoservice/schema'
@@ -0,0 +1,78 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'validator'
4
+ require 'ant/storage'
5
+
6
+ module Ant
7
+ module Nanoservice
8
+ # This module is a factory of types. This will provide a class from the
9
+ # configurations, attaching all the validations requested.
10
+ # Currently it only plugs the validations and the repository inside the
11
+ # factory so you can start using them on your code
12
+ module MetaTypes
13
+ extend Ant::DRY::ResourceInjector
14
+
15
+ class << self
16
+ include Ant::Storage::Exceptions
17
+ def validation_builder(fields)
18
+ fields.each_with_object({}) do |(field, plugins), obj|
19
+ obj[field.to_sym] = plugins.map do |plug, conf|
20
+ Validator.validator(plug).curry.call(conf)
21
+ end
22
+ end
23
+ end
24
+
25
+ def build_constructor(klass)
26
+ klass.define_method :initialize do |data|
27
+ @data = {}
28
+ data.each do |key, val|
29
+ case key
30
+ when Symbol
31
+ @data[key] = val if self.class::VALIDATIONS.key?(key)
32
+ when String
33
+ if self.class::VALIDATIONS.keys.map(&:to_s).include?(key)
34
+ @data[key.to_sym] = val
35
+ end
36
+ end
37
+ end
38
+ end
39
+ end
40
+
41
+ def build_validation_errors_method(klass)
42
+ klass.define_method :validation_errors do
43
+ result = {}
44
+ self.class::VALIDATIONS.each do |key, validation|
45
+ problems = validation.map { |val| val.call(@data[key]) }.compact
46
+ result[key] = problems unless problems.empty?
47
+ end
48
+ result
49
+ end
50
+ klass.define_method :run_validations! do
51
+ errors = validation_errors
52
+ raise ValidationErrors, errors unless errors.empty?
53
+ end
54
+ end
55
+
56
+ def primary_keys(fields)
57
+ fields.select { |_, conf| conf['keys'] && conf['keys']['primary'] }
58
+ .keys
59
+ .first
60
+ &.to_sym
61
+ end
62
+
63
+ def build(name, fields, _configs)
64
+ validations = validation_builder(fields)
65
+ klass = Class.new(Ant::Storage::Datasource::Model)
66
+ build_constructor(klass)
67
+ build_validation_errors_method(klass)
68
+ class_name = name.split('_').collect(&:capitalize).join
69
+ MetaTypes.const_set(class_name, klass)
70
+ klass.const_set('VALIDATIONS', validations)
71
+ klass.const_set('NAME', name)
72
+ klass.const_set('PRIMARY_KEY', primary_keys(fields))
73
+ klass
74
+ end
75
+ end
76
+ end
77
+ end
78
+ end
@@ -0,0 +1,60 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'ant/storage'
4
+
5
+ require_relative 'metatypes'
6
+
7
+ module Ant
8
+ module Nanoservice
9
+ # Takes a configuration and creates the metaclasess, repositories and
10
+ # factory from them.
11
+ # this can be attached to Grape API as helpers and provide a connection
12
+ # to the data layer.
13
+ class Schema
14
+ attr_reader :schema, :repositories
15
+
16
+ def initialize(schema)
17
+ build_schemas(schema['models'])
18
+ build_repositories(schema['models'], schema['repositories'])
19
+ end
20
+
21
+ private
22
+
23
+ def build_schemas(models)
24
+ @schema_configs = {}
25
+ @schema = models.each_with_object({}) do |(name, configs), obj|
26
+ columns = configs['fields']
27
+ @schema_configs[name] = configs
28
+ configs['configs']['schema_name'] = name
29
+ obj[name] = MetaTypes.build(name, columns, configs)
30
+ end
31
+ end
32
+
33
+ def build_repositories(models, repository_conf)
34
+ @repositories = models.each_with_object({}) do |(name, _), obj|
35
+ obj[name] = Ant::Storage::Repository
36
+ .from_config(@schema[name],
37
+ @schema_configs[name]['configs'],
38
+ repository_conf['default'])
39
+ end
40
+ end
41
+
42
+ public
43
+
44
+ def mount_grape_helpers(api, schema_name)
45
+ model = schema[schema_name]
46
+ repo = repositories[schema_name]
47
+ api.helpers do
48
+ define_method('factory') do
49
+ @factory ||= begin
50
+ factory = Ant::Storage::Factory.new(model)
51
+ factory.register(:default, :primary)
52
+ factory.register(:primary, repo)
53
+ factory
54
+ end
55
+ end
56
+ end
57
+ end
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,78 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'ant/storage'
4
+
5
+ module Ant
6
+ module Nanoservice
7
+ # This module is a singleton that stores all the validator plugins
8
+ # A validator plugin is introduced into metatypes and used to validate
9
+ # that types are properly validated.
10
+ # See more on the validators documentations.
11
+ module Validator
12
+ extend Ant::DRY::ResourceInjector
13
+ def self.register_plugin(name)
14
+ block = lambda do |value, conf|
15
+ yield(value, conf) ? nil : "#{name} failed!"
16
+ end
17
+ register(:validators, name, block)
18
+ end
19
+
20
+ def self.validator_alias(name, new_name)
21
+ validator = resource(:validators, name)
22
+ register(:validators, new_name, validator)
23
+ end
24
+
25
+ def self.register_type(type)
26
+ block = proc { |value| yield(value) }
27
+ register(:types, type, block)
28
+ end
29
+
30
+ def self.type_alias(type, new_name)
31
+ validator = resource(:types, type)
32
+ register(:types, new_name, validator)
33
+ end
34
+
35
+ def self.validator(name)
36
+ resource(:validators, name)
37
+ end
38
+
39
+ register_plugin('keys') do |_conf, _val|
40
+ true
41
+ end
42
+
43
+ register_plugin('range') do |conf, val|
44
+ val.nil? || (conf['min']..conf['max']).cover?(val)
45
+ end
46
+
47
+ register_plugin('not_nil') do |_conf, val|
48
+ !val.nil?
49
+ end
50
+
51
+ validator_alias('not_nil', 'not_null')
52
+
53
+ register_plugin('size') do |size, val|
54
+ val.nil? || val.size <= size
55
+ end
56
+
57
+ validator_alias('size', 'length')
58
+
59
+ register_plugin('pattern') do |regex, val|
60
+ val.nil? || Regexp.new(regex).match?(val)
61
+ end
62
+ validator_alias('pattern', 'regex')
63
+
64
+ register_plugin('type') do |type, val|
65
+ type_validator = resource(:types, type)
66
+ val.nil? || type_validator.call(val)
67
+ end
68
+
69
+ register_type('numeric') { |val| val.is_a?(Numeric) }
70
+ register_type('text') { |val| val.is_a?(String) }
71
+ register_type('int') { |val| val.is_a?(Integer) }
72
+ register_type('date') { |val| val.is_a?(Date) }
73
+ register_type('timestamp') { |val| val.is_a?(DateTime) }
74
+
75
+ type_alias('text', 'string')
76
+ end
77
+ end
78
+ end
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Ant
4
+ module Nanoservice
5
+ VERSION = '0.1.0'
6
+ end
7
+ end
metadata ADDED
@@ -0,0 +1,189 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: ant-nanoservice
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Gilberto Vargas
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2019-10-07 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: ant-core
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '0.1'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '0.1'
27
+ - !ruby/object:Gem::Dependency
28
+ name: ant-storage
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '0.1'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '0.1'
41
+ - !ruby/object:Gem::Dependency
42
+ name: minitest
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '5.11'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '5.11'
55
+ - !ruby/object:Gem::Dependency
56
+ name: mocha
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '1.8'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '1.8'
69
+ - !ruby/object:Gem::Dependency
70
+ name: pry
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: '0.12'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: '0.12'
83
+ - !ruby/object:Gem::Dependency
84
+ name: rack-minitest
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: '0.0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: '0.0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: rake
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - "~>"
102
+ - !ruby/object:Gem::Version
103
+ version: '12.3'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - "~>"
109
+ - !ruby/object:Gem::Version
110
+ version: '12.3'
111
+ - !ruby/object:Gem::Dependency
112
+ name: rdoc
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - "~>"
116
+ - !ruby/object:Gem::Version
117
+ version: '6.1'
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - "~>"
123
+ - !ruby/object:Gem::Version
124
+ version: '6.1'
125
+ - !ruby/object:Gem::Dependency
126
+ name: simplecov
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - "~>"
130
+ - !ruby/object:Gem::Version
131
+ version: '0.16'
132
+ type: :development
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - "~>"
137
+ - !ruby/object:Gem::Version
138
+ version: '0.16'
139
+ - !ruby/object:Gem::Dependency
140
+ name: webmock
141
+ requirement: !ruby/object:Gem::Requirement
142
+ requirements:
143
+ - - "~>"
144
+ - !ruby/object:Gem::Version
145
+ version: '3.5'
146
+ type: :development
147
+ prerelease: false
148
+ version_requirements: !ruby/object:Gem::Requirement
149
+ requirements:
150
+ - - "~>"
151
+ - !ruby/object:Gem::Version
152
+ version: '3.5'
153
+ description: Helps to create CRUD objects from a config
154
+ email:
155
+ - tachoguitar@gmail.com
156
+ executables: []
157
+ extensions: []
158
+ extra_rdoc_files: []
159
+ files:
160
+ - lib/ant.rb
161
+ - lib/ant/nanoservice.rb
162
+ - lib/ant/nanoservice/metatypes.rb
163
+ - lib/ant/nanoservice/schema.rb
164
+ - lib/ant/nanoservice/validator.rb
165
+ - lib/ant/nanoservice/version.rb
166
+ homepage: https://github.com/tachomex/ant
167
+ licenses:
168
+ - MIT
169
+ metadata: {}
170
+ post_install_message:
171
+ rdoc_options: []
172
+ require_paths:
173
+ - lib
174
+ required_ruby_version: !ruby/object:Gem::Requirement
175
+ requirements:
176
+ - - ">="
177
+ - !ruby/object:Gem::Version
178
+ version: '0'
179
+ required_rubygems_version: !ruby/object:Gem::Requirement
180
+ requirements:
181
+ - - ">="
182
+ - !ruby/object:Gem::Version
183
+ version: '0'
184
+ requirements: []
185
+ rubygems_version: 3.0.3
186
+ signing_key:
187
+ specification_version: 4
188
+ summary: Implements CRUD from yaml file
189
+ test_files: []