carbonyte 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: f88398d2111a4b6f2423dd798eb0d629fb7e9f78b54d49eea3b6fe28d60590ef
4
+ data.tar.gz: ddf8b9fe408fa7f2fa8b85bdc7157db5bfd07aa17fb165d68c76c7e7148b6d6e
5
+ SHA512:
6
+ metadata.gz: 7875ec1d6d77312e7d7a0ad4f9f2db33aae0db243ca0d4d9edcb55ec4d90816d94027821d6e7abeb9a06757064da42a84fccb9becb8097cbea19fe0f9047733c
7
+ data.tar.gz: 5ff2e50321cb295d0726465488d2094152c30c63849c5af32bfb2a4b17dd70bb573a595d53d0d9a2306b42a54ff4c5ce8d371602728997515cc84df2e8ef55ab
@@ -0,0 +1,22 @@
1
+ # Carbonyte
2
+ Build Microservices-oriented Architectures with ease.
3
+
4
+ ## Installation
5
+ Add this line to your microservice Gemfile:
6
+
7
+ ```ruby
8
+ gem 'carbonyte'
9
+ ```
10
+
11
+ And then execute:
12
+ ```bash
13
+ $ bundle
14
+ ```
15
+
16
+ ## Usage
17
+ TBD
18
+
19
+ ## Contributing
20
+ Before pushing:
21
+ * Run `rubocop` to show code styles offences
22
+ * Run `inch` to show documentation state
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ begin
4
+ require 'bundler/setup'
5
+ rescue LoadError
6
+ puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
7
+ end
8
+
9
+ require 'rdoc/task'
10
+
11
+ RDoc::Task.new(:rdoc) do |rdoc|
12
+ rdoc.rdoc_dir = 'rdoc'
13
+ rdoc.title = 'Carbonyte'
14
+ rdoc.options << '--line-numbers'
15
+ rdoc.rdoc_files.include('README.md')
16
+ rdoc.rdoc_files.include('lib/**/*.rb')
17
+ end
18
+
19
+ load 'rails/tasks/statistics.rake'
20
+
21
+ require 'bundler/gem_tasks'
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Carbonyte
4
+ # Carbonyte base class for all controllers
5
+ class ApplicationController < ActionController::API
6
+ end
7
+ end
@@ -0,0 +1,61 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Carbonyte
4
+ # The Rescuable concern rescues controllers from bubbling up the most common exceptions
5
+ # and provides a uniformed response body in case of such errors.
6
+ # @see https://jsonapi.org/format/#error-objects
7
+ module Rescuable
8
+ extend ActiveSupport::Concern
9
+
10
+ included do
11
+ rescue_from Pundit::NotAuthorizedError, with: :unauthorized
12
+ rescue_from Interactor::Failure, with: :interactor_failure
13
+ rescue_from ActiveRecord::RecordInvalid, with: :record_invalid
14
+ end
15
+
16
+ private
17
+
18
+ def serialized_errors(payload)
19
+ payload = [payload] unless payload.is_a?(Enumerable)
20
+ payload.to_json
21
+ end
22
+
23
+ def unauthorized(exc)
24
+ payload = {
25
+ code: exc.class.name,
26
+ source: { policy: exc.policy.class.name },
27
+ title: 'Not Authorized By Policy',
28
+ detail: exc.message
29
+ }
30
+ render json: serialized_errors(payload), status: :unauthorized
31
+ end
32
+
33
+ def interactor_failure(exc)
34
+ payload = {
35
+ code: exc.class.name,
36
+ source: { interactor: exc.context._called.last.class.name },
37
+ title: 'Interactor Failure',
38
+ detail: exc.context.error
39
+ }
40
+ render json: serialized_errors(payload), status: :unprocessable_entity
41
+ end
42
+
43
+ def record_invalid(exc)
44
+ payload = errors_for_record(exc.record, exc.class.name).flatten
45
+ render json: serialized_errors(payload), status: :unprocessable_entity
46
+ end
47
+
48
+ def errors_for_record(record, code)
49
+ record.messages.map do |field, errors|
50
+ errors.map do |error_message|
51
+ {
52
+ code: code,
53
+ source: { pointer: "attributes/#{field}" },
54
+ title: 'Invalid Field ',
55
+ detail: error_message
56
+ }
57
+ end
58
+ end
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Carbonyte
4
+ # Carbonyte base class for all interactors
5
+ class ApplicationInteractor
6
+ include Interactor
7
+ end
8
+ end
@@ -0,0 +1,68 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Carbonyte
4
+ # Carbonyte module for Finders.
5
+ # Finders are Interactors whose main task is to build a query
6
+ module Finders
7
+ # Carbonyte base class for all finders interactors.
8
+ # Finders are used to build queries based on parameters
9
+ class ApplicationFinder < ApplicationInteractor
10
+ # Default limit for pagination
11
+ DEFAULT_LIMIT = 25
12
+
13
+ # Starts building the query (:scope)
14
+ #
15
+ # @option context:params [Hash] the parameters used to build the query scope
16
+ # @option context:params:include [String] a comma-separated list of relations to include
17
+ # @option context:params:sort [String] a comma-separated list of columns to use to sort.
18
+ # If the "-" prefix is provided then the sort will be descending, ascending otherwise
19
+ # @option context:params:limit [Integer] the number of items per page.
20
+ # Defaults to +DEFAULT_LIMIT+
21
+ # @option context:params:page [Integer] the page to load. Defaults to 1
22
+ def call
23
+ include_relations if context.params[:include].present?
24
+ sort if context.params[:sort].present?
25
+ paginate
26
+ end
27
+
28
+ protected
29
+
30
+ # Returns true if the provided relation can be included
31
+ # @param _rel [Symbol] the relation to include
32
+ def can_include?(_rel)
33
+ false
34
+ end
35
+
36
+ private
37
+
38
+ def include_relations
39
+ context.params[:include].split(',').each do |relation|
40
+ next unless can_include?(relation)
41
+
42
+ context.scope = context.scope.includes(relation)
43
+ end
44
+ end
45
+
46
+ def sort_properties
47
+ context.params[:sort].split(',')
48
+ end
49
+
50
+ def sort_exp(prop)
51
+ return prop unless prop.start_with?('-')
52
+
53
+ { prop[1..] => :desc }
54
+ end
55
+
56
+ def sort
57
+ sort_properties.each do |prop|
58
+ context.scope = context.scope.order(sort_exp(prop))
59
+ end
60
+ end
61
+
62
+ def paginate
63
+ context.scope = context.scope.limit(context.params[:limit] || DEFAULT_LIMIT)
64
+ context.scope = context.scope.page(context.params[:page] || 1)
65
+ end
66
+ end
67
+ end
68
+ end
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Carbonyte
4
+ # Carbonyte base class for all models
5
+ class ApplicationRecord < ActiveRecord::Base
6
+ self.abstract_class = true
7
+ end
8
+ end
@@ -0,0 +1,40 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Carbonyte
4
+ # Carbonyte base class for all serializers
5
+ class ApplicationSerializer
6
+ include JSONAPI::Serializer
7
+
8
+ # Initializes the serializer.
9
+ # @param resource [Object] the resource(s) to serialize
10
+ # @param options [Hash] the serializer options.
11
+ # @see https://github.com/jsonapi-serializer/jsonapi-serializer/blob/master/README.md
12
+ def initialize(resource, options = {})
13
+ parse_options(resource, options)
14
+ super
15
+ end
16
+
17
+ private
18
+
19
+ # Adds additional options automatically based on the resource
20
+ def parse_options(resource, options)
21
+ resource_options = if resource.is_a?(Enumerable)
22
+ options_for_list(resource)
23
+ else
24
+ options_for_object(resource)
25
+ end
26
+ options.merge!(resource_options)
27
+ end
28
+
29
+ # For collections, the :meta option will be added to support pagination
30
+ def options_for_list(list)
31
+ options = {}
32
+ options[:meta] = { total: list.total_entries } if list.respond_to?(:total_entries)
33
+ options
34
+ end
35
+
36
+ def options_for_object(_resource)
37
+ {}
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,4 @@
1
+ # frozen_string_literal: true
2
+
3
+ Carbonyte::Engine.routes.draw do
4
+ end
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'carbonyte/engine'
4
+
5
+ # Main Carbonyte module
6
+ module Carbonyte
7
+ end
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Carbonyte
4
+ # Carbonyte Engine
5
+ class Engine < ::Rails::Engine
6
+ isolate_namespace Carbonyte
7
+ end
8
+ end
@@ -0,0 +1,6 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Carbonyte
4
+ # Carbonyte version
5
+ VERSION = '0.1.0'
6
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+ # desc "Explaining what the task does"
3
+ # task :carbonyte do
4
+ # # Task goes here
5
+ # end
metadata ADDED
@@ -0,0 +1,146 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: carbonyte
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - iMacTia
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2020-08-11 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: interactor-rails
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '2.0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '2.0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: jsonapi-serializer
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '2.0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '2.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: pundit
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '2.1'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '2.1'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rails
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: 6.0.3
62
+ - - ">="
63
+ - !ruby/object:Gem::Version
64
+ version: 6.0.3.2
65
+ type: :runtime
66
+ prerelease: false
67
+ version_requirements: !ruby/object:Gem::Requirement
68
+ requirements:
69
+ - - "~>"
70
+ - !ruby/object:Gem::Version
71
+ version: 6.0.3
72
+ - - ">="
73
+ - !ruby/object:Gem::Version
74
+ version: 6.0.3.2
75
+ - !ruby/object:Gem::Dependency
76
+ name: inch
77
+ requirement: !ruby/object:Gem::Requirement
78
+ requirements:
79
+ - - "~>"
80
+ - !ruby/object:Gem::Version
81
+ version: 0.8.0
82
+ type: :development
83
+ prerelease: false
84
+ version_requirements: !ruby/object:Gem::Requirement
85
+ requirements:
86
+ - - "~>"
87
+ - !ruby/object:Gem::Version
88
+ version: 0.8.0
89
+ - !ruby/object:Gem::Dependency
90
+ name: rspec-rails
91
+ requirement: !ruby/object:Gem::Requirement
92
+ requirements:
93
+ - - "~>"
94
+ - !ruby/object:Gem::Version
95
+ version: '4.0'
96
+ type: :development
97
+ prerelease: false
98
+ version_requirements: !ruby/object:Gem::Requirement
99
+ requirements:
100
+ - - "~>"
101
+ - !ruby/object:Gem::Version
102
+ version: '4.0'
103
+ description: Carbonyte is the core of great Microservices-oriented Architectures.
104
+ email:
105
+ - giuffrida.mattia@gmail.com
106
+ executables: []
107
+ extensions: []
108
+ extra_rdoc_files: []
109
+ files:
110
+ - README.md
111
+ - Rakefile
112
+ - app/controllers/carbonyte/application_controller.rb
113
+ - app/controllers/carbonyte/concerns/rescuable.rb
114
+ - app/interactors/carbonyte/application_interactor.rb
115
+ - app/interactors/carbonyte/finders/application_finder.rb
116
+ - app/models/carbonyte/application_record.rb
117
+ - app/serializers/carbonyte/application_serializer.rb
118
+ - config/routes.rb
119
+ - lib/carbonyte.rb
120
+ - lib/carbonyte/engine.rb
121
+ - lib/carbonyte/version.rb
122
+ - lib/tasks/carbonyte_tasks.rake
123
+ homepage: https://github.com/iMacTia/carbonyte
124
+ licenses:
125
+ - Copyright
126
+ metadata: {}
127
+ post_install_message:
128
+ rdoc_options: []
129
+ require_paths:
130
+ - lib
131
+ required_ruby_version: !ruby/object:Gem::Requirement
132
+ requirements:
133
+ - - ">="
134
+ - !ruby/object:Gem::Version
135
+ version: '0'
136
+ required_rubygems_version: !ruby/object:Gem::Requirement
137
+ requirements:
138
+ - - ">="
139
+ - !ruby/object:Gem::Version
140
+ version: '0'
141
+ requirements: []
142
+ rubygems_version: 3.1.2
143
+ signing_key:
144
+ specification_version: 4
145
+ summary: Build Microservices-oriented Architectures with ease
146
+ test_files: []