upframework 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 03201d4216dd3b35c2fc0868ab19a0c11f3b98f5e50a3e139934011732604073
4
+ data.tar.gz: 90775fb0f00abfae7d19b8b7ee132c456a7dac32ab7de9e26f89799bce1d7b08
5
+ SHA512:
6
+ metadata.gz: be618352e1e443df2da7bedbe9b91d54db1acf0d98dbb42f7858568102480a0a847b706644368b840771bd3b6e116469d3d500b766b686ae42228ea5aa8b7e71
7
+ data.tar.gz: 2c8395e1c8ef62b1ca8e58b3c6247a2742068cea4f2c3051e189b2a3e1517528d3f9522bcf90be229cb90d64297e0a484d65db86777c3d3816d164fb59946c80
data/MIT-LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright 2020 jude_cali
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,28 @@
1
+ # Upframework
2
+ Short description and motivation.
3
+
4
+ ## Usage
5
+ How to use my plugin.
6
+
7
+ ## Installation
8
+ Add this line to your application's Gemfile:
9
+
10
+ ```ruby
11
+ gem 'upframework'
12
+ ```
13
+
14
+ And then execute:
15
+ ```bash
16
+ $ bundle
17
+ ```
18
+
19
+ Or install it yourself as:
20
+ ```bash
21
+ $ gem install upframework
22
+ ```
23
+
24
+ ## Contributing
25
+ Contribution directions go here.
26
+
27
+ ## License
28
+ The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
data/Rakefile ADDED
@@ -0,0 +1,32 @@
1
+ begin
2
+ require 'bundler/setup'
3
+ rescue LoadError
4
+ puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
5
+ end
6
+
7
+ require 'rdoc/task'
8
+
9
+ RDoc::Task.new(:rdoc) do |rdoc|
10
+ rdoc.rdoc_dir = 'rdoc'
11
+ rdoc.title = 'Upframework'
12
+ rdoc.options << '--line-numbers'
13
+ rdoc.rdoc_files.include('README.md')
14
+ rdoc.rdoc_files.include('lib/**/*.rb')
15
+ end
16
+
17
+ APP_RAKEFILE = File.expand_path("test/dummy/Rakefile", __dir__)
18
+ load 'rails/tasks/engine.rake'
19
+
20
+ load 'rails/tasks/statistics.rake'
21
+
22
+ require 'bundler/gem_tasks'
23
+
24
+ require 'rake/testtask'
25
+
26
+ Rake::TestTask.new(:test) do |t|
27
+ t.libs << 'test'
28
+ t.pattern = 'test/**/*_test.rb'
29
+ t.verbose = false
30
+ end
31
+
32
+ task default: :test
@@ -0,0 +1 @@
1
+ //= link_directory ../stylesheets/upframework .css
@@ -0,0 +1,15 @@
1
+ /*
2
+ * This is a manifest file that'll be compiled into application.css, which will include all the files
3
+ * listed below.
4
+ *
5
+ * Any CSS and SCSS file within this directory, lib/assets/stylesheets, vendor/assets/stylesheets,
6
+ * or any plugin's vendor/assets/stylesheets directory can be referenced here using a relative path.
7
+ *
8
+ * You're free to add application-wide styles to this file and they'll appear at the bottom of the
9
+ * compiled file so the styles you add here take precedence over styles defined in any other CSS/SCSS
10
+ * files in this directory. Styles in this file should be added after the last require_* statement.
11
+ * It is generally better to create a new file per style scope.
12
+ *
13
+ *= require_tree .
14
+ *= require_self
15
+ */
@@ -0,0 +1,99 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Upframework::CrudExtensions
4
+ extend ::ActiveSupport::Concern
5
+
6
+ included do
7
+ before_action :set_base_resource
8
+ end
9
+
10
+ def show
11
+ base_resource
12
+
13
+ yield if block_given?
14
+ render_serialized base_resource
15
+ end
16
+
17
+ def update
18
+ if base_resource.update(base_resource_params)
19
+ yield if block_given?
20
+ render_serialized base_resource
21
+ else
22
+ render_errors base_resource.errors.full_messages
23
+ end
24
+ end
25
+
26
+ def index
27
+ base_resource
28
+
29
+ yield if block_given?
30
+ render_serialized base_resource, includes: params[:includes]
31
+ end
32
+
33
+ def create
34
+ if base_resource.save
35
+
36
+ yield if block_given?
37
+ render_serialized base_resource
38
+ else
39
+ render_errors base_resource.errors.full_messages
40
+ end
41
+ end
42
+
43
+ def destroy
44
+ base_resource.destroy
45
+ head :no_content
46
+ end
47
+
48
+ private
49
+
50
+ def base_resource
51
+ if params[:id]
52
+ instance_variable_get("@#{base_resource_name}")
53
+ else
54
+ instance_variable_get("@#{base_resource_name.pluralize}")
55
+ end
56
+ end
57
+
58
+ def set_base_resource
59
+ data =
60
+ if params[:id]
61
+ base_resource_class.find(params[:id])
62
+ elsif action_name == 'index'
63
+ base_resource_class.accessible_by(current_ability).where(base_resource_params || {})
64
+ elsif action_name == 'create'
65
+ base_resource_class.new(base_resource_params)
66
+ end
67
+
68
+ resource_name = %w[index create].include?(action_name) \
69
+ ? base_resource_name.pluralize \
70
+ : base_resource_name
71
+
72
+ instance_variable_set("@#{resource_name}", data) if data
73
+ end
74
+
75
+ def base_resource_params
76
+ base_name = base_resource_name
77
+
78
+ base_name = base_name.pluralize unless params.key?(base_name)
79
+
80
+ params.fetch(base_name).permit(*permitted_columns)
81
+ end
82
+
83
+ def permitted_columns
84
+ columns = base_resource_class.accessible_fields_by(accessors)
85
+ columns.concat(extra_params)
86
+ end
87
+
88
+ def accessors
89
+ current_user
90
+ end
91
+
92
+ def base_resource_name
93
+ controller_name.singularize
94
+ end
95
+
96
+ def base_resource_class
97
+ base_resource_name.classify.safe_constantize
98
+ end
99
+ end
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Upframework::ErrorHandler
4
+ extend ActiveSupport::Concern
5
+
6
+ included do
7
+ rescue_from StandardError do |e|
8
+ handle_exception(e)
9
+ end
10
+
11
+ protected
12
+
13
+ def handle_exception(error)
14
+ raise error if Rails.env.development?
15
+
16
+ ExceptionNotifier.notify_exception(error, env: request.env)
17
+
18
+ error_info = {
19
+ error: 'Internal Server Error',
20
+ exception: "#{error.class.name} : #{error.message}"
21
+ }
22
+
23
+ render json: error_info, status: :internal_server_error
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,56 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Upframework
4
+ module RenderExtensions
5
+ extend ActiveSupport::Concern
6
+
7
+ included do
8
+ # Args
9
+ # resource => instance of model
10
+ # include => include relations on response
11
+ # format => format can be :full(returns all default) or :minimal(returns only ids an types)
12
+ # compound_opts => options, e.g: meta or links
13
+ # opts => extra options from render
14
+ def render_serialized(resource, includes: [], format: :full, compound_opts: {}, **opts)
15
+ render json: serialize_resource(resource, includes, format, compound_opts), **opts
16
+ end
17
+
18
+ # Args
19
+ # resource => instance of model
20
+ # channel => channel on where to broadcast response. If not provided will use the resource
21
+ # include => include relations on response
22
+ # format => format can be :full(returns all default) or :minimal(returns only ids an types)
23
+ # compound_opts => options, e.g: meta or links
24
+ # opts => extra options from render
25
+ def broadcast_serialized(channel, resource:, event:, includes: [], format: :full, compound_opts: {})
26
+ includes << :events
27
+ resource.add_event(event, creator: current_member)
28
+
29
+ channel_klass = "::#{channel.class.name}Channel".constantize
30
+ channel_klass.broadcast_to(channel, serialize_resource(resource, includes, format, compound_opts))
31
+ end
32
+
33
+ def render_errors(error_messages, status: :unprocessable_entity)
34
+ render json: { errors: error_messages }, status: status
35
+ end
36
+
37
+ protected
38
+
39
+ def serialize_resource(resource, includes, format, compound_opts)
40
+ resource_klass = resource.class.name
41
+ if resource_klass == 'ActiveRecord::Relation'
42
+ resource_klass = resource.klass.name
43
+ end
44
+ # TODO: support empty arrays
45
+ resource_klass = resource.first.class.name if resource.is_a? Array
46
+
47
+ serializer_klass = "#{resource_klass}Serializer".constantize
48
+
49
+ relations = serializer_klass.default_includes
50
+ relations.concat(Array(includes).map(&:to_sym)) if includes
51
+
52
+ serializer_klass.new(resource, include: relations, format: format, current_controller: self, **compound_opts).serializable_hash
53
+ end
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,21 @@
1
+ module Upframework::TransformParamKeys
2
+ extend ActiveSupport::Concern
3
+
4
+ included do
5
+ prepend_before_action :underscore_params!
6
+
7
+ def underscore_params!
8
+ request.parameters.deep_transform_keys!(&:underscore)
9
+
10
+ resource_name = controller_name.singularize
11
+ resource_klass = resource_name.classify.safe_constantize
12
+ attributes = resource_klass ? resource_klass.column_names.map(&:to_sym) : []
13
+
14
+ attributes.concat(extra_params) if respond_to?(:extra_params, true)
15
+
16
+ if resource_klass && params.key?(resource_name) && params[resource_name].class != Array
17
+ params[resource_name].merge! params.permit(*attributes)
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,33 @@
1
+ module Upframework
2
+ class ApiController < ::ApplicationController
3
+ include ::DeviseTokenAuth::Concerns::SetUserByToken
4
+ include ::Upframework::ErrorHandler
5
+ include ::Upframework::TransformParamKeys
6
+ include ::Upframework::CrudExtensions
7
+ include ::Upframework::RenderExtensions
8
+ include ::Upframework::ServiceActionController
9
+
10
+ before_action :authenticate!
11
+
12
+ # need to skip this on non-resource controller
13
+ # > skip_authorize_resource
14
+ authorize_resource
15
+
16
+ rescue_from CanCan::AccessDenied do |exception|
17
+ respond_to do |format|
18
+ format.json { render json: { success: false, error: exception.message }, status: :forbidden }
19
+ format.html { redirect_to main_app.root_url, alert: exception.message }
20
+ end
21
+ end
22
+
23
+ def authenticate!
24
+ super || authenticate_user!
25
+ end
26
+
27
+ protected
28
+
29
+ def extra_params
30
+ [] # Override in specific controllers for custom params
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,4 @@
1
+ module Upframework
2
+ module ApplicationHelper
3
+ end
4
+ end
@@ -0,0 +1,4 @@
1
+ module Upframework
2
+ class ApplicationJob < ActiveJob::Base
3
+ end
4
+ end
@@ -0,0 +1,6 @@
1
+ module Upframework
2
+ class ApplicationMailer < ActionMailer::Base
3
+ default from: 'from@example.com'
4
+ layout 'mailer'
5
+ end
6
+ end
@@ -0,0 +1,5 @@
1
+ module Upframework
2
+ class ApplicationRecord < ActiveRecord::Base
3
+ self.abstract_class = true
4
+ end
5
+ end
@@ -0,0 +1,29 @@
1
+ module Upframework
2
+ module ServiceActionController
3
+ extend ::ActiveSupport::Concern
4
+
5
+ included do
6
+ def service
7
+ service = service_class.run(**params.to_unsafe_h.symbolize_keys)
8
+
9
+ if service.success?
10
+ render_serialized service.result
11
+ else
12
+ render_errors service.errors
13
+ end
14
+ end
15
+
16
+ private
17
+
18
+ def service_class
19
+ base_resource_name = controller_name.classify.pluralize
20
+ service_name = params[:service_name]&.classify
21
+
22
+ service_class = "::#{base_resource_name}::#{service_name}Service".safe_constantize
23
+ raise ActionController::RoutingError.new('Not Found') if service_class.nil?
24
+
25
+ service_class
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,15 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <title>Upframework</title>
5
+ <%= csrf_meta_tags %>
6
+ <%= csp_meta_tag %>
7
+
8
+ <%= stylesheet_link_tag "upframework/application", media: "all" %>
9
+ </head>
10
+ <body>
11
+
12
+ <%= yield %>
13
+
14
+ </body>
15
+ </html>
data/config/routes.rb ADDED
@@ -0,0 +1,3 @@
1
+ Upframework::Engine.routes.draw do
2
+ ::Upframework::Services::Routes.load
3
+ end
@@ -0,0 +1,4 @@
1
+ # desc "Explaining what the task does"
2
+ # task :upframework do
3
+ # # Task goes here
4
+ # end
@@ -0,0 +1,5 @@
1
+ module Upframework
2
+ class Engine < ::Rails::Engine
3
+ isolate_namespace Upframework
4
+ end
5
+ end
@@ -0,0 +1,19 @@
1
+ module Upframework
2
+ module Services
3
+ module Routes
4
+ def self.load
5
+ Rails.application.routes.draw do
6
+ source_path = Rails.root.join('app', 'services')
7
+
8
+ namespace :api, defaults: { format: 'json' } do
9
+ Dir.glob("#{source_path}/*/").map{ |e| File.basename e }.each do |resource|
10
+ #TODO: check resource exists in controller
11
+ # config to exclude some services in the routes
12
+ post "#{resource}/service/:service_name", to: "#{resource}#service"
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,3 @@
1
+ module Upframework
2
+ VERSION = '0.1.0'
3
+ end
@@ -0,0 +1,7 @@
1
+ require "upframework/engine"
2
+
3
+ module Upframework
4
+ # Your code goes here...
5
+ end
6
+
7
+ require "upframework/services/routes"
metadata ADDED
@@ -0,0 +1,85 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: upframework
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - jude_cali
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2020-04-02 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rails
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: 6.0.2
20
+ - - ">="
21
+ - !ruby/object:Gem::Version
22
+ version: 6.0.2.1
23
+ type: :runtime
24
+ prerelease: false
25
+ version_requirements: !ruby/object:Gem::Requirement
26
+ requirements:
27
+ - - "~>"
28
+ - !ruby/object:Gem::Version
29
+ version: 6.0.2
30
+ - - ">="
31
+ - !ruby/object:Gem::Version
32
+ version: 6.0.2.1
33
+ description: Rails framework extensions
34
+ email:
35
+ - jcalimbas@fullscale.io
36
+ executables: []
37
+ extensions: []
38
+ extra_rdoc_files: []
39
+ files:
40
+ - MIT-LICENSE
41
+ - README.md
42
+ - Rakefile
43
+ - app/assets/config/upframework_manifest.js
44
+ - app/assets/stylesheets/upframework/application.css
45
+ - app/controllers/concerns/upframework/crud_extensions.rb
46
+ - app/controllers/concerns/upframework/error_handler.rb
47
+ - app/controllers/concerns/upframework/render_extensions.rb
48
+ - app/controllers/concerns/upframework/transform_param_keys.rb
49
+ - app/controllers/upframework/api_controller.rb
50
+ - app/helpers/upframework/application_helper.rb
51
+ - app/jobs/upframework/application_job.rb
52
+ - app/mailers/upframework/application_mailer.rb
53
+ - app/models/upframework/application_record.rb
54
+ - app/services/concerns/service_action_controller.rb
55
+ - app/views/layouts/upframework/application.html.erb
56
+ - config/routes.rb
57
+ - lib/tasks/upframework_tasks.rake
58
+ - lib/upframework.rb
59
+ - lib/upframework/engine.rb
60
+ - lib/upframework/services/routes.rb
61
+ - lib/upframework/version.rb
62
+ homepage: https://gitlab.com/disruptors/upframework
63
+ licenses:
64
+ - MIT
65
+ metadata: {}
66
+ post_install_message:
67
+ rdoc_options: []
68
+ require_paths:
69
+ - lib
70
+ required_ruby_version: !ruby/object:Gem::Requirement
71
+ requirements:
72
+ - - ">="
73
+ - !ruby/object:Gem::Version
74
+ version: '0'
75
+ required_rubygems_version: !ruby/object:Gem::Requirement
76
+ requirements:
77
+ - - ">="
78
+ - !ruby/object:Gem::Version
79
+ version: '0'
80
+ requirements: []
81
+ rubygems_version: 3.0.3
82
+ signing_key:
83
+ specification_version: 4
84
+ summary: Rails framework extensions
85
+ test_files: []