endpoint-flux2 1.1.6

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 (93) hide show
  1. checksums.yaml +7 -0
  2. data/.github/FUNDING.yml +3 -0
  3. data/.github/workflows/gem-push.yml +42 -0
  4. data/.gitignore +36 -0
  5. data/CONTRIBUTING.md +18 -0
  6. data/Gemfile +6 -0
  7. data/Gemfile.lock +49 -0
  8. data/README.md +634 -0
  9. data/Rakefile +1 -0
  10. data/_config.yml +1 -0
  11. data/circle.yml +14 -0
  12. data/endpoint_flux.gemspec +20 -0
  13. data/lib/endpoint_flux.rb +22 -0
  14. data/lib/endpoint_flux/class_loader.rb +58 -0
  15. data/lib/endpoint_flux/config.rb +85 -0
  16. data/lib/endpoint_flux/config/interceptor.rb +23 -0
  17. data/lib/endpoint_flux/config/middleware.rb +38 -0
  18. data/lib/endpoint_flux/config/rescue_from.rb +28 -0
  19. data/lib/endpoint_flux/endpoint.rb +81 -0
  20. data/lib/endpoint_flux/exceptions.rb +10 -0
  21. data/lib/endpoint_flux/exceptions/base.rb +21 -0
  22. data/lib/endpoint_flux/exceptions/forbidden.rb +12 -0
  23. data/lib/endpoint_flux/exceptions/not_found.rb +12 -0
  24. data/lib/endpoint_flux/exceptions/service_unavailable.rb +12 -0
  25. data/lib/endpoint_flux/exceptions/unauthorized.rb +12 -0
  26. data/lib/endpoint_flux/exceptions/validation.rb +13 -0
  27. data/lib/endpoint_flux/middlewares.rb +8 -0
  28. data/lib/endpoint_flux/middlewares/authenticator/skip.rb +11 -0
  29. data/lib/endpoint_flux/middlewares/authorizator/skip.rb +11 -0
  30. data/lib/endpoint_flux/middlewares/decorator/add_status.rb +12 -0
  31. data/lib/endpoint_flux/middlewares/decorator/skip.rb +11 -0
  32. data/lib/endpoint_flux/middlewares/policy/skip.rb +11 -0
  33. data/lib/endpoint_flux/middlewares/validator/empty.rb +12 -0
  34. data/lib/endpoint_flux/rails/concerns/endpoint_controller.rb +43 -0
  35. data/lib/endpoint_flux/railtie.rb +14 -0
  36. data/lib/endpoint_flux/request.rb +17 -0
  37. data/lib/endpoint_flux/response.rb +30 -0
  38. data/lib/endpoint_flux/tasks/endpoint_flux/generators/endpoint_flux/decorators/articles/base.rb +12 -0
  39. data/lib/endpoint_flux/tasks/endpoint_flux/generators/endpoint_flux/decorators/boards/base.rb +12 -0
  40. data/lib/endpoint_flux/tasks/endpoint_flux/generators/endpoint_flux/decorators/boards/show.rb +22 -0
  41. data/lib/endpoint_flux/tasks/endpoint_flux/generators/endpoint_flux/decorators/tasks/base.rb +12 -0
  42. data/lib/endpoint_flux/tasks/endpoint_flux/generators/endpoint_flux/endpoints/articles/create.rb +27 -0
  43. data/lib/endpoint_flux/tasks/endpoint_flux/generators/endpoint_flux/endpoints/articles/destroy.rb +23 -0
  44. data/lib/endpoint_flux/tasks/endpoint_flux/generators/endpoint_flux/endpoints/articles/index.rb +26 -0
  45. data/lib/endpoint_flux/tasks/endpoint_flux/generators/endpoint_flux/endpoints/boards/create.rb +24 -0
  46. data/lib/endpoint_flux/tasks/endpoint_flux/generators/endpoint_flux/endpoints/boards/index.rb +21 -0
  47. data/lib/endpoint_flux/tasks/endpoint_flux/generators/endpoint_flux/endpoints/boards/show.rb +23 -0
  48. data/lib/endpoint_flux/tasks/endpoint_flux/generators/endpoint_flux/endpoints/tasks/create.rb +27 -0
  49. data/lib/endpoint_flux/tasks/endpoint_flux/generators/endpoint_flux/endpoints/tasks/destroy.rb +23 -0
  50. data/lib/endpoint_flux/tasks/endpoint_flux/generators/endpoint_flux/endpoints/tasks/index.rb +25 -0
  51. data/lib/endpoint_flux/tasks/endpoint_flux/generators/endpoint_flux/endpoints/tasks/update.rb +28 -0
  52. data/lib/endpoint_flux/tasks/endpoint_flux/generators/endpoint_flux/middlewares/decorator/paginate.rb +19 -0
  53. data/lib/endpoint_flux/tasks/endpoint_flux/generators/endpoint_flux/middlewares/decorator/representable.rb +24 -0
  54. data/lib/endpoint_flux/tasks/endpoint_flux/generators/endpoint_flux/middlewares/validator/inline.rb +17 -0
  55. data/lib/endpoint_flux/tasks/endpoint_flux/generators/endpoint_flux/validations/base.rb +21 -0
  56. data/lib/endpoint_flux/tasks/endpoint_flux/generators/endpoint_flux/validations/concern/error.rb +7 -0
  57. data/lib/endpoint_flux/tasks/endpoint_flux/generators/endpoint_flux/validations/predicates/base.rb +12 -0
  58. data/lib/endpoint_flux/tasks/endpoint_flux/generators/endpoint_flux/validations/predicates/bool.rb +20 -0
  59. data/lib/endpoint_flux/tasks/endpoint_flux/generators/endpoint_flux/validations/predicates/dates.rb +34 -0
  60. data/lib/endpoint_flux/tasks/endpoint_flux/generators/endpoint_flux/validations/predicates/decimal.rb +24 -0
  61. data/lib/endpoint_flux/tasks/endpoint_flux/generators/endpoint_flux/validations/predicates/email.rb +18 -0
  62. data/lib/endpoint_flux/tasks/endpoint_flux/generators/endpoint_flux/validations/predicates/password.rb +29 -0
  63. data/lib/endpoint_flux/tasks/endpoint_flux/generators/initializers/endpoint_flux.rb +41 -0
  64. data/lib/endpoint_flux/tasks/endpoint_flux/init.rake +12 -0
  65. data/lib/endpoint_flux/version.rb +3 -0
  66. data/spec/lib/class_loader_spec.rb +31 -0
  67. data/spec/lib/config/default_middlewares_spec.rb +21 -0
  68. data/spec/lib/config/endpoints_namespace_spec.rb +13 -0
  69. data/spec/lib/config/flow_spec.rb +8 -0
  70. data/spec/lib/config/interceptor_spec.rb +34 -0
  71. data/spec/lib/config/middleware_spec.rb +62 -0
  72. data/spec/lib/config/rescue_from_spec.rb +45 -0
  73. data/spec/lib/endpoint/flow_spec.rb +43 -0
  74. data/spec/lib/endpoint/middlewares_spec.rb +110 -0
  75. data/spec/lib/endpoint/perform_spec.rb +61 -0
  76. data/spec/lib/endpoint/rescue_from_spec.rb +61 -0
  77. data/spec/lib/endpoint_flux/rails/concerns/endpoint_controller_spec.rb +158 -0
  78. data/spec/lib/endpoint_flux/request_spec.rb +44 -0
  79. data/spec/lib/exceptions/forbidden_spec.rb +12 -0
  80. data/spec/lib/exceptions/not_found_spec.rb +12 -0
  81. data/spec/lib/exceptions/service_unavailable_spec.rb +12 -0
  82. data/spec/lib/exceptions/unauthorized_spec.rb +12 -0
  83. data/spec/lib/exceptions/validation_spec.rb +14 -0
  84. data/spec/lib/middlewares/authenticator/skip_spec.rb +5 -0
  85. data/spec/lib/middlewares/authorizator/skip_spec.rb +5 -0
  86. data/spec/lib/middlewares/decorator/add_status_spec.rb +17 -0
  87. data/spec/lib/middlewares/decorator/skip_spec.rb +5 -0
  88. data/spec/lib/middlewares/policy/skip_spec.rb +5 -0
  89. data/spec/lib/middlewares/shared_examples.rb +19 -0
  90. data/spec/lib/middlewares/validator/empty_spec.rb +15 -0
  91. data/spec/lib/response_spec.rb +131 -0
  92. data/spec/spec_helper.rb +56 -0
  93. metadata +203 -0
@@ -0,0 +1,12 @@
1
+ module EndpointFlux
2
+ module Exceptions
3
+ class ServiceUnavailable < EndpointFlux::Exceptions::Base
4
+ def to_hash
5
+ {
6
+ status: 503,
7
+ message: 'service unavailable'
8
+ }
9
+ end
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,12 @@
1
+ module EndpointFlux
2
+ module Exceptions
3
+ class Unauthorized < EndpointFlux::Exceptions::Base
4
+ def to_hash
5
+ {
6
+ status: 401,
7
+ message: 'Unauthorized'
8
+ }
9
+ end
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,13 @@
1
+ module EndpointFlux
2
+ module Exceptions
3
+ class Validation < EndpointFlux::Exceptions::Base
4
+ def to_hash
5
+ {
6
+ status: 422,
7
+ message: 'validation errors',
8
+ errors: @messages
9
+ }
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,8 @@
1
+ module Middlewares
2
+ require_relative 'middlewares/authenticator/skip'
3
+ require_relative 'middlewares/authorizator/skip'
4
+ require_relative 'middlewares/decorator/skip'
5
+ require_relative 'middlewares/decorator/add_status'
6
+ require_relative 'middlewares/policy/skip'
7
+ require_relative 'middlewares/validator/empty'
8
+ end
@@ -0,0 +1,11 @@
1
+ module EndpointFlux
2
+ module Middlewares
3
+ module Authenticator
4
+ module Skip
5
+ def self.perform(*args, _options)
6
+ args
7
+ end
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,11 @@
1
+ module EndpointFlux
2
+ module Middlewares
3
+ module Authorizator
4
+ module Skip
5
+ def self.perform(*args, _opts)
6
+ args
7
+ end
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,12 @@
1
+ module EndpointFlux
2
+ module Middlewares
3
+ module Decorator
4
+ module AddStatus
5
+ def self.perform(request, response, status)
6
+ response.body[:status] = status
7
+ [request, response]
8
+ end
9
+ end
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,11 @@
1
+ module EndpointFlux
2
+ module Middlewares
3
+ module Decorator
4
+ module Skip
5
+ def self.perform(*args, _options)
6
+ args
7
+ end
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,11 @@
1
+ module EndpointFlux
2
+ module Middlewares
3
+ module Policy
4
+ module Skip
5
+ def self.perform(*args, _options)
6
+ args
7
+ end
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,12 @@
1
+ module EndpointFlux
2
+ module Middlewares
3
+ module Validator
4
+ module Empty
5
+ def self.perform(request, response, _options)
6
+ request.params = {}
7
+ [request, response]
8
+ end
9
+ end
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,43 @@
1
+ module EndpointFlux
2
+ module Rails
3
+ module Concerns
4
+ module EndpointController
5
+ extend ActiveSupport::Concern
6
+
7
+ def present(namespace)
8
+ _, response = endpoint_for(namespace).perform(request_object)
9
+
10
+ headers.merge! response.headers
11
+ render json: response.body
12
+ end
13
+
14
+ def endpoint_for(namespace)
15
+ return namespace unless ::EndpointFlux.config.endpoints_namespace
16
+ (::EndpointFlux.config.endpoints_namespace + '/' + namespace).camelize.constantize
17
+ end
18
+
19
+ def request_object
20
+ ::EndpointFlux::Request.new(
21
+ headers: headers.merge('Authorization' => request.headers['authorization']),
22
+ remote_ip: remote_ip,
23
+ params: endpoint_params
24
+ )
25
+ end
26
+
27
+ def endpoint_params
28
+ params.permit!.except(:controller, :action, :format).to_h.deep_symbolize_keys
29
+ end
30
+
31
+ def remote_ip
32
+ ip = request.remote_ip.to_s
33
+
34
+ if ip == '127.0.0.1'
35
+ ip = request.env['HTTP_X_FORWARDED_FOR']
36
+ end
37
+
38
+ ip
39
+ end
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,14 @@
1
+ require 'endpoint_flux'
2
+ require 'rails'
3
+
4
+ module EndpointFlux
5
+ class Railtie < Rails::Railtie
6
+ railtie_name :endpoint_flux
7
+
8
+ rake_tasks do
9
+ path = File.expand_path(__dir__)
10
+ Dir.glob("#{path}/tasks/**/*.rake").each { |f| load f }
11
+ end
12
+ end
13
+ end
14
+
@@ -0,0 +1,17 @@
1
+ module EndpointFlux
2
+ class Request
3
+ def initialize(headers: {}, remote_ip: '', params: {}, namespace: nil)
4
+ @headers = headers
5
+ @remote_ip = remote_ip
6
+ @params = params
7
+ @namespace = namespace
8
+ end
9
+
10
+ attr_accessor :params
11
+ attr_accessor :headers
12
+ attr_accessor :remote_ip
13
+ attr_accessor :namespace
14
+ attr_accessor :endpoint
15
+ attr_accessor :scope
16
+ end
17
+ end
@@ -0,0 +1,30 @@
1
+ module EndpointFlux
2
+ class Response
3
+ def initialize(headers: {}, body: {})
4
+ @body = body
5
+ @headers = headers
6
+ end
7
+
8
+ attr_accessor :body, :headers
9
+
10
+ def success?
11
+ body[:status] && body[:status].between?(200, 209)
12
+ end
13
+
14
+ def invalid?
15
+ body[:status] == 422
16
+ end
17
+
18
+ def forbidden?
19
+ body[:status] == 403
20
+ end
21
+
22
+ def unauthorized?
23
+ body[:status] == 401
24
+ end
25
+
26
+ def not_found?
27
+ body[:status] == 404
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,12 @@
1
+ module Decorators
2
+ module Articles
3
+ class Base < Representable::Decorator
4
+ include Representable::JSON
5
+
6
+ property :id
7
+ property :name
8
+ property :board_id
9
+
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,12 @@
1
+ module Decorators
2
+ module Boards
3
+ class Base < Representable::Decorator
4
+ include Representable::JSON
5
+
6
+ property :id
7
+ property :name
8
+ property :link
9
+
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,22 @@
1
+ module Decorators
2
+ module Boards
3
+ class Show < Representable::Decorator
4
+ include Representable::JSON
5
+
6
+ property :id
7
+ property :name
8
+ property :link
9
+ collection :articles do
10
+ property :id
11
+ property :name
12
+ property :board_id
13
+ collection :tasks do
14
+ property :id
15
+ property :title
16
+ property :article_id
17
+ end
18
+ end
19
+
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,12 @@
1
+ module Decorators
2
+ module Tasks
3
+ class Base < Representable::Decorator
4
+ include Representable::JSON
5
+
6
+ property :id
7
+ property :title
8
+ property :article_id
9
+
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,27 @@
1
+ module Endpoints
2
+ module Articles
3
+ module Create
4
+ include EndpointFlux::Endpoint
5
+
6
+ validator :inline do
7
+ required(:name).value(:str?)
8
+ required(:board_id).value(:number?)
9
+ end
10
+
11
+ process do |request, response|
12
+ article = Article.create!(
13
+ name: request.params[:name],
14
+ board_id: request.params[:board_id]
15
+ )
16
+
17
+ response.body[:article] = article
18
+
19
+ [request, response]
20
+ end
21
+
22
+ decorator :add_status, 201
23
+ decorator :representable,
24
+ decorator: 'Articles::Base', wrapped_in: :article
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,23 @@
1
+ module Endpoints
2
+ module Articles
3
+ module Destroy
4
+ include EndpointFlux::Endpoint
5
+
6
+ validator :inline do
7
+ required(:id).value(:number?)
8
+ end
9
+
10
+ process do |request, response|
11
+ article = Article.find(request.params[:id]).destroy
12
+
13
+ response.body[:article] = article
14
+
15
+ [request, response]
16
+ end
17
+
18
+ decorator :add_status, 202
19
+ decorator :representable,
20
+ decorator: 'Articles::Base', wrapped_in: :article
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,26 @@
1
+ module Endpoints
2
+ module Articles
3
+ module Index
4
+ include EndpointFlux::Endpoint
5
+
6
+ authorizator :skip
7
+
8
+ validator :inline do
9
+ required(:board_id).value(:number?)
10
+ end
11
+
12
+ process do |request, response|
13
+
14
+ response.body[:articles] = Article.where(board_id: request.params[:board_id])
15
+
16
+ [request, response]
17
+ end
18
+
19
+ decorator :add_status, 200
20
+ decorator :paginate, wrapped_in: :articles
21
+ decorator :representable, decorator: 'Articles::Base',
22
+ collection?: true,
23
+ wrapped_in: :articles
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,24 @@
1
+ #
2
+ module Endpoints
3
+ module Boards
4
+ module Create
5
+ include EndpointFlux::Endpoint
6
+
7
+ validator :inline do
8
+ required(:name).value(:str?)
9
+ end
10
+
11
+ process do |request, response|
12
+ link = SecureRandom.hex(20)
13
+ board = Board.create!(name: request.params[:name], link: link)
14
+
15
+ response.body[:board] = board
16
+
17
+ [request, response]
18
+ end
19
+
20
+ decorator :add_status, 201
21
+ decorator :representable, decorator: 'Boards::Base', wrapped_in: :board
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,21 @@
1
+ module Endpoints
2
+ module Boards
3
+ module Index
4
+ include EndpointFlux::Endpoint
5
+
6
+ authorizator :skip
7
+
8
+ process do |request, response|
9
+
10
+ response.body[:boards] = Board.all
11
+
12
+ [request, response]
13
+ end
14
+
15
+ decorator :add_status, 200
16
+ decorator :representable, decorator: 'Boards::Base',
17
+ collection?: true,
18
+ wrapped_in: :boards
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,23 @@
1
+ module Endpoints
2
+ module Boards
3
+ module Show
4
+ include EndpointFlux::Endpoint
5
+
6
+ authorizator :skip
7
+
8
+ validator :inline do
9
+ required(:link).value(:str?)
10
+ end
11
+ process do |request, response|
12
+
13
+ response.body[:board] = Board.find_by(link: request.params[:link])
14
+
15
+ [request, response]
16
+ end
17
+
18
+ decorator :add_status, 200
19
+ decorator :representable, decorator: 'Boards::Show',
20
+ wrapped_in: :board
21
+ end
22
+ end
23
+ end