hippo-fw 0.9.1 → 0.9.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (127) hide show
  1. checksums.yaml +4 -4
  2. data/.ruby-version +1 -1
  3. data/Gemfile +16 -11
  4. data/Rakefile +0 -7
  5. data/bin/hippo +5 -1
  6. data/client/hippo/__mocks__/config.js +2 -3
  7. data/client/hippo/boot.jsx +0 -2
  8. data/client/hippo/components/asset.jsx +1 -1
  9. data/client/hippo/components/form.jsx +8 -4
  10. data/client/hippo/components/form/fields.jsx +28 -14
  11. data/client/hippo/components/form/model.js +65 -20
  12. data/client/hippo/components/form/wrapper.jsx +11 -5
  13. data/client/hippo/components/icon.jsx +1 -1
  14. data/client/hippo/components/master-detail.jsx +66 -0
  15. data/client/hippo/components/master-detail.scss +50 -0
  16. data/client/hippo/components/record-finder.jsx +5 -5
  17. data/client/hippo/components/tool-tip.jsx +20 -0
  18. data/client/hippo/config.js +5 -3
  19. data/client/hippo/extensions/base.js +4 -0
  20. data/client/hippo/lib/smooth-scroll.js +17 -16
  21. data/client/hippo/models/asset.js +8 -10
  22. data/client/hippo/models/collection.js +1 -4
  23. data/client/hippo/models/query/array-result.js +11 -9
  24. data/client/hippo/models/sync.js +3 -3
  25. data/client/hippo/models/tenant.js +29 -0
  26. data/client/hippo/screens/system-settings.jsx +5 -4
  27. data/client/hippo/screens/system-settings/mailer-config.jsx +11 -17
  28. data/client/hippo/screens/system-settings/tenant.jsx +90 -0
  29. data/client/hippo/screens/user-management/edit-form.jsx +15 -25
  30. data/client/hippo/testing/index.js +1 -0
  31. data/client/hippo/workspace/styles.scss +0 -23
  32. data/command-reference-files/initial/.babelrc +10 -8
  33. data/command-reference-files/initial/Gemfile +1 -1
  34. data/{views/index.html → command-reference-files/initial/views/index.erb} +1 -0
  35. data/config/routes.rb +48 -17
  36. data/config/webpack.config.js +7 -12
  37. data/db/migrate/01_create_tenants.rb +13 -0
  38. data/db/migrate/{01_create_system_settings.rb → 02_create_system_settings.rb} +2 -1
  39. data/db/migrate/{02_create_assets.rb → 03_create_assets.rb} +2 -4
  40. data/db/migrate/{20140615031600_create_users.rb → 04_create_users.rb} +4 -2
  41. data/db/seed.rb +10 -1
  42. data/hippo-fw.gemspec +53 -51
  43. data/lib/hippo.rb +7 -1
  44. data/lib/hippo/access.rb +0 -1
  45. data/lib/hippo/access/roles/basic_user.rb +2 -0
  46. data/lib/hippo/api.rb +4 -3
  47. data/lib/hippo/{access → api}/authentication_provider.rb +3 -1
  48. data/lib/hippo/api/controller_base.rb +2 -2
  49. data/lib/hippo/api/handlers/asset.rb +28 -2
  50. data/lib/hippo/api/handlers/tenant.rb +26 -0
  51. data/lib/hippo/api/helper_methods.rb +5 -13
  52. data/lib/hippo/api/request_wrapper.rb +8 -1
  53. data/lib/hippo/api/root.rb +50 -51
  54. data/lib/hippo/api/route_set.rb +101 -0
  55. data/lib/hippo/api/routing.rb +9 -98
  56. data/lib/hippo/api/tenant_domain_router.rb +21 -0
  57. data/lib/hippo/asset.rb +1 -0
  58. data/lib/hippo/command.rb +1 -24
  59. data/lib/hippo/command/app.rb +4 -3
  60. data/lib/hippo/command/console.rb +7 -0
  61. data/lib/hippo/command/generate.rb +0 -5
  62. data/lib/hippo/command/guard.rb +1 -0
  63. data/lib/hippo/command/jest.rb +2 -2
  64. data/lib/hippo/command/server.rb +1 -3
  65. data/lib/hippo/command/webpack.rb +6 -26
  66. data/lib/hippo/configuration.rb +21 -13
  67. data/lib/hippo/db.rb +2 -0
  68. data/lib/hippo/db/migrations.rb +9 -2
  69. data/lib/hippo/extension.rb +49 -14
  70. data/lib/hippo/extension/definition.rb +0 -4
  71. data/lib/hippo/guard_tasks.rb +3 -11
  72. data/lib/hippo/mailer.rb +28 -16
  73. data/lib/hippo/model.rb +10 -0
  74. data/lib/hippo/numbers.rb +1 -1
  75. data/lib/hippo/rake_tasks.rb +7 -1
  76. data/lib/hippo/spec_helper.rb +33 -11
  77. data/lib/hippo/system_settings.rb +1 -0
  78. data/lib/hippo/templates/base.rb +1 -1
  79. data/lib/hippo/templates/mail.rb +26 -0
  80. data/lib/hippo/templates/tenant_change.rb +23 -0
  81. data/lib/hippo/tenant.rb +53 -0
  82. data/lib/hippo/user.rb +12 -6
  83. data/lib/hippo/version.rb +1 -1
  84. data/lib/hippo/webpack.rb +57 -0
  85. data/lib/hippo/{command → webpack}/client_config.rb +7 -21
  86. data/package.json +3 -3
  87. data/spec/client/components/__snapshots__/master-detail.spec.jsx.snap +22 -0
  88. data/spec/client/components/form.spec.jsx +14 -14
  89. data/spec/client/components/master-detail.spec.jsx +24 -0
  90. data/spec/client/components/record-finder.spec.jsx +5 -2
  91. data/spec/client/models/asset.spec.js +2 -13
  92. data/spec/client/models/base.spec.js +1 -11
  93. data/spec/client/models/query.spec.js +2 -4
  94. data/spec/client/models/sync.spec.js +7 -0
  95. data/spec/client/screens/__snapshots__/system-settings.spec.jsx.snap +79 -0
  96. data/spec/client/screens/system-settings-tenants.spec.jsx +18 -0
  97. data/spec/client/workspace/__snapshots__/menu.spec.jsx.snap +29 -313
  98. data/spec/client/workspace/menu.spec.jsx +1 -9
  99. data/spec/factories/tenant.rb +13 -0
  100. data/spec/fixtures/mail/test_email.liquid +1 -0
  101. data/spec/fixtures/{test_printer.tex → test_printer.tex.erb} +0 -0
  102. data/spec/server/api/controller_base_spec.rb +1 -1
  103. data/spec/server/api/tenant_change_spec.rb +24 -0
  104. data/spec/server/api/tenant_isolation_spec.rb +37 -0
  105. data/spec/server/asset_spec.rb +6 -6
  106. data/spec/server/command_spec.rb +0 -5
  107. data/spec/server/mailer_spec.rb +25 -23
  108. data/spec/server/numbers_spec.rb +12 -13
  109. data/spec/server/print/form_spec.rb +2 -1
  110. data/spec/server/strings_spec.rb +13 -13
  111. data/templates/.babelrc +10 -8
  112. data/templates/js/screen-definitions.js +8 -10
  113. data/templates/mail/tenant_change.liquid +13 -0
  114. data/{command-reference-files/initial/views/index.html → views/index.erb} +5 -2
  115. data/yarn.lock +22 -169
  116. metadata +56 -30
  117. data/client/hippo/components/form/field-prop-type.js +0 -16
  118. data/lib/hippo/api/default_routes.rb +0 -38
  119. data/lib/hippo/command/generate_component.rb +0 -28
  120. data/lib/hippo/command/generate_component.usage +0 -11
  121. data/lib/hippo/command/webpack_view.rb +0 -32
  122. data/lib/hippo/multi_server_boot.rb +0 -26
  123. data/lib/hippo/reloadable_view.rb +0 -13
  124. data/templates/client/components/.gitkeep +0 -0
  125. data/templates/client/components/BaseComponent.coffee +0 -9
  126. data/templates/client/components/Component.cjsx +0 -4
  127. data/templates/client/components/template.html +0 -3
@@ -1,5 +1,6 @@
1
1
  require 'active_record'
2
2
  require 'pathname'
3
+ require 'require_all'
3
4
 
4
5
  module Hippo
5
6
  ROOT_PATH = Pathname.new(__FILE__).dirname.join('..')
@@ -19,6 +20,7 @@ require_relative "hippo/numbers"
19
20
  require_relative "hippo/concerns/all"
20
21
  require_relative "hippo/validators/all"
21
22
  require_relative "hippo/model"
23
+ require_relative 'hippo/tenant'
22
24
  require_relative "hippo/system_settings"
23
25
  require_relative "hippo/asset"
24
26
  require_relative "hippo/extension"
@@ -26,9 +28,13 @@ require_relative "hippo/screen"
26
28
  require_relative "hippo/job"
27
29
  require_relative "hippo/job/failure_logger"
28
30
  require_relative "hippo/templates/base"
29
- require_relative "hippo/templates/latex"
30
31
  require_relative "hippo/templates/liquid"
32
+ require_relative "hippo/templates/latex"
33
+ require_relative "hippo/templates/mail"
34
+ require_rel 'hippo/templates/*.rb'
35
+
31
36
  require_relative "hippo/mailer"
32
37
  require_relative 'hippo/user'
33
38
  require_relative "hippo/access"
34
39
  require_relative "hippo/workspace"
40
+ require_relative "hippo/webpack"
@@ -42,7 +42,6 @@ module Hippo
42
42
 
43
43
  end
44
44
 
45
- require_relative 'access/authentication_provider'
46
45
  require_relative 'access/locked_fields'
47
46
  require_relative 'access/role'
48
47
  require_relative 'access/role_collection'
@@ -5,6 +5,8 @@ module Hippo
5
5
 
6
6
  class BasicUser < Role
7
7
 
8
+ self.read << Hippo::Tenant
9
+
8
10
  end
9
11
 
10
12
  end
@@ -9,9 +9,10 @@ require_relative 'api/cable'
9
9
  require_relative 'api/sprockets_extension'
10
10
  require_relative 'api/helper_methods'
11
11
  require_relative 'api/pub_sub'
12
- require_relative 'api/handlers/user_session'
13
- require_relative 'api/handlers/asset'
14
- require_relative 'api/handlers/print'
12
+ require_rel 'api/handlers/*.rb'
13
+ require_relative 'api/route_set'
14
+ require_relative "api/authentication_provider"
15
+ require_relative 'api/tenant_domain_router'
15
16
  require_relative 'api/root'
16
17
 
17
18
  module Hippo
@@ -3,7 +3,7 @@ module Hippo
3
3
  class AuthenticationProvider
4
4
 
5
5
  def self.user_for_request(request)
6
- token = request.params['jwt']
6
+ token = request.env['HTTP_AUTHORIZATION']
7
7
  token ? User.for_jwt_token(token) : nil
8
8
  end
9
9
 
@@ -32,6 +32,7 @@ module Hippo
32
32
  end
33
33
 
34
34
  def allowed_access_to?(klass, options = {})
35
+
35
36
  return true if options[:public] == true and current_user.nil?
36
37
  return false if current_user.nil?
37
38
  case request.request_method
@@ -57,6 +58,7 @@ module Hippo
57
58
  end
58
59
 
59
60
  def wrap_model_access(model, req, options = {})
61
+ fail_request(req) and return unless Tenant.current
60
62
  if allowed_access_to?(model, options)
61
63
  ::Hippo::User.scoped_to(current_user) do | user |
62
64
  yield
@@ -61,7 +61,7 @@ module Hippo
61
61
  end
62
62
 
63
63
  def perform_multiple_destroy
64
- query = model.where(id: data.map{|rec|rec['id']})
64
+ query = model.where(id: data.map { |rec| rec['id'] })
65
65
  query = add_access_limits_to_query(query)
66
66
  success = true
67
67
  query.each do |record|
@@ -74,7 +74,7 @@ module Hippo
74
74
  end
75
75
 
76
76
  def perform_multiple_updates
77
- query = model.where(id: data.map {|rec|rec['id'] })
77
+ query = model.where(id: data.map { |rec| rec['id'] })
78
78
  query = add_access_limits_to_query(query)
79
79
  success = true
80
80
  query.each do |record|
@@ -28,11 +28,37 @@ module Hippo::API::Handlers
28
28
  end
29
29
  end
30
30
 
31
- def self.getter
31
+ def self.file_getter
32
32
  root = Hippo::Extensions.controlling.root_path.join('public', 'files')
33
33
  lambda do
34
- send_file(root.join( params['splat'].first ).to_s)
34
+ send_file(root.join(params['splat'].first).to_s)
35
35
  end
36
36
  end
37
+
38
+ def self.asset_getter
39
+ root = Hippo::Extensions.controlling.root_path.join('public', 'assets')
40
+ webpack = Hippo::API::Root.webpack
41
+ if Hippo.env.production?
42
+ lambda do
43
+ file = webpack.file(params['asset'].to_sym, raise_on_not_found: false)
44
+ if file
45
+ redirect "/assets/#{file}"
46
+ else
47
+ halt 404
48
+ end
49
+ end
50
+ else
51
+ lambda do
52
+ webpack.wait_until_available
53
+ file = webpack.file(params['asset'].to_sym, raise_on_not_found: false)
54
+ if file
55
+ redirect "http://#{env['SERVER_NAME']}:#{webpack.process.port}/assets/#{file}"
56
+ else
57
+ halt 404
58
+ end
59
+ end
60
+ end
61
+ end
62
+
37
63
  end
38
64
  end
@@ -0,0 +1,26 @@
1
+ module Hippo::API::Handlers
2
+
3
+ class Tenant < Hippo::API::ControllerBase
4
+ PUBLIC_ATTRS = %w{slug name}
5
+
6
+ def show
7
+ std_api_reply(:retrieve, Hippo::Tenant.current, only: PUBLIC_ATTRS)
8
+ end
9
+
10
+ # isn't really a create, but FE will think it's creating because we don't expose the id
11
+ def create
12
+ tenant = Hippo::Tenant.current
13
+ tenant.assign_attributes(data.slice(*PUBLIC_ATTRS))
14
+ success = tenant.save
15
+ if success
16
+ Hippo::Tenant.system.perform do
17
+ Hippo::Templates::TenantChange.create(tenant).deliver
18
+ end
19
+ end
20
+ std_api_reply(:update, tenant,
21
+ only: PUBLIC_ATTRS,
22
+ success: success)
23
+ end
24
+ end
25
+
26
+ end
@@ -5,19 +5,11 @@ module Hippo
5
5
  Extensions.controlling.title
6
6
  end
7
7
 
8
- def hippo_javascript_tags
9
- []
10
- # assets = API.webpack.assets.map do | k |
11
- # "<script src=\"http://localhost:#{API.webpack.port}/#{k}\"></script>"
12
- # end
13
- # assets.join("\n")
14
-
15
- # "<script src=\"http://localhost:#{API.webpack.port}/hippo.js\"></script>"
16
- # javascript_tag('hippo/vendor') + "\n" + javascript_tag('hippo')
17
- end
18
-
19
- def hippo_stylesheet_tags
20
- # stylesheet_tag('hippo')
8
+ def javascript_tags(*entries)
9
+ Root.webpack.wait_until_available
10
+ entries.map { |entry|
11
+ "<script src=\"#{Root.webpack.host}/assets/#{Root.webpack.file(entry)}\"></script>"
12
+ }.join("\n")
21
13
  end
22
14
 
23
15
  def client_bootstrap_data(mergedWith: {})
@@ -72,7 +72,14 @@ module Hippo
72
72
  #
73
73
  # @param [options] options for additional checks
74
74
  # @option opts [Boolean] :with_transaction rollback DB transaction if exceptions occur
75
- def wrap_reply(options = {with_transaction: true})
75
+ # @option opts [Boolean] :require_tenant return error if tenant is not found
76
+ def wrap_reply(options = { with_transaction: true, require_tenant: true })
77
+ if options[:require_tenant] && Hippo::Tenant.current.nil?
78
+ return json_reply(
79
+ { success: false, message: "invalid address",
80
+ errors: { address: 'invalid' } }
81
+ )
82
+ end
76
83
  response = { success: false, message: "No response was generated" }
77
84
  log_request
78
85
  if options[:with_transaction]
@@ -3,68 +3,67 @@ require 'oj'
3
3
  require 'rack/protection'
4
4
  require 'rack/cors'
5
5
 
6
- require_relative "../access/authentication_provider"
6
+ module Hippo::API
7
+ class Root < Sinatra::Application
8
+ CORS_PATHS = {}
7
9
 
8
- module Hippo
9
- module API
10
- class Root < Sinatra::Application
11
- CORS_PATHS = {}
12
-
13
- Hippo.config.get(:environment) do | env |
14
- set :environment, env
15
- end
16
- helpers RequestWrapper
17
- helpers HelperMethods
18
- helpers FormattedReply
19
-
20
- use Rack::Session::Cookie,
21
- :key => 'rack.session',
22
- :secret => Hippo.config.session_secret_key_base
23
- not_found do
24
- Oj.dump({ message: "endpoint not found", success: false })
25
- end
26
- error ActiveRecord::RecordNotFound do
27
- halt 404, error_as_json
28
- end
29
- error do
30
- error_as_json
31
- end
10
+ Hippo.config.get(:environment) do | env |
11
+ set :environment, env
12
+ end
13
+ helpers RequestWrapper
14
+ helpers HelperMethods
15
+ helpers FormattedReply
16
+ use TenantDomainRouter
17
+ use Rack::Session::Cookie,
18
+ :key => 'rack.session',
19
+ :secret => Hippo.config.session_secret_key_base
20
+ not_found do
21
+ Oj.dump({ message: "endpoint not found", success: false })
22
+ end
32
23
 
33
- configure do
34
- set :show_exceptions, false
35
- require_relative 'routing'
36
- Hippo::Configuration.apply
37
- Extensions.load_controlling_config
24
+ error ActiveRecord::RecordNotFound do
25
+ halt 404, error_as_json
26
+ end
38
27
 
39
- set :views, Extensions.controlling.root_path.join('views')
28
+ error do
29
+ error_as_json
30
+ end
40
31
 
41
- require_relative './default_routes'
42
- API::Cable.configure
43
- end
32
+ configure do
33
+ set :show_exceptions, false
34
+ Hippo::Configuration.apply
35
+ Hippo::Extensions.load_controlling_config
36
+ set :views, Hippo::Extensions.controlling.root_path.join('views')
37
+ set :webpack, Hippo::Webpack.new
38
+ webpack.start
39
+ require_relative './routing'
40
+ Cable.configure
41
+ cors_resources = []
42
+ if CORS_PATHS.any?
43
+ use Rack::Cors,
44
+ debug: !Hippo.env.production?,
45
+ logger: Hippo.logger do
44
46
 
45
- configure do
46
- cors_resources = []
47
- if API::Root::CORS_PATHS.any?
48
- use Rack::Cors, debug: !Hippo.env.production?, logger: Hippo.logger do
49
- API::Root::CORS_PATHS.each do | path, options |
50
- allow do
51
- cors_resources.push Rack::Cors::Resource.new('', path)
52
- origins options[:origins]
53
- resource path,
54
- :methods => options[:methods].map(&:to_sym) + [:options],
55
- :headers => :any
56
- end
47
+ CORS_PATHS.each do | path, options |
48
+ allow do
49
+ cors_resources.push Rack::Cors::Resource.new('', path)
50
+ origins options[:origins]
51
+ resource path,
52
+ :methods => options[:methods].map(&:to_sym) + [:options],
53
+ :headers => :any
57
54
  end
58
-
59
55
  end
60
56
 
61
57
  end
62
- # use Rack::Protection, allow_if: -> (env) {
63
- # path = env['PATH_INFO']
64
- # cors_resources.any?{|r| r.matches_path?(path) }
65
- # }
66
58
 
67
59
  end
60
+
61
+ use Rack::Protection, allow_if: -> (env) {
62
+ path = env['PATH_INFO']
63
+ cors_resources.any?{|r| r.matches_path?(path) }
64
+ }
68
65
  end
66
+
69
67
  end
68
+
70
69
  end
@@ -0,0 +1,101 @@
1
+ module Hippo
2
+ module API
3
+
4
+ class RoutingBlock
5
+ def initialize(ext_id)
6
+ Hippo::Extensions.for_identifier(ext_id) ||
7
+ raise( "Unable to find extension '#{ext_id}' for screen group")
8
+ @ext_id = ext_id
9
+ end
10
+
11
+ [:get, :post, :put, :patch, :delete].each do | method_name |
12
+ define_method(method_name) do | path_suffix, options = {}, &block |
13
+ API::Root.send(method_name, make_path(path_suffix), options, &block)
14
+ end
15
+ end
16
+
17
+ def enable_cors(path_suffix, options = {origins: '*', methods: [:get]})
18
+ API::Root::CORS_PATHS[make_path(path_suffix)] = options
19
+ end
20
+
21
+ def resources(model, options = {})
22
+ path = options[:path] || model.api_path
23
+ controller = options[:controller] || Hippo::API::GenericController
24
+ format = options[:format] || '.json'
25
+ if options[:under]
26
+ options[:parent_attribute] = options[:under].underscore.singularize+'_id'
27
+ end
28
+
29
+ prefix = options[:parent_attribute] ? options[:parent_attribute] + '/' : ''
30
+
31
+ valid_methods = []
32
+
33
+ bind = lambda{ |method, route, wrapper_method = method|
34
+ valid_methods.push(method)
35
+ self.send(method, route + format,
36
+ &RequestWrapper.send(wrapper_method, model, controller, options))
37
+ }
38
+
39
+ # show
40
+ if controller.method_defined?(:show)
41
+ bind[:get, "#{prefix}#{path}/?:id?"]
42
+ end
43
+
44
+ # create
45
+ if controller.method_defined?(:create)
46
+ bind[:post, "#{prefix}#{path}"]
47
+ end
48
+
49
+ unless options[:immutable]
50
+
51
+ # update
52
+ if controller.method_defined?(:update)
53
+ bind[:patch, "#{prefix}#{path}/?:id?", :update]
54
+ bind[:put, "#{prefix}#{path}/?:id?", :update]
55
+ end
56
+
57
+ # destroy
58
+ if controller.method_defined?(:destroy) and not options[:indestructible]
59
+ bind[:delete, "#{prefix}#{path}/?:id?"]
60
+ end
61
+
62
+ end
63
+
64
+ if options[:cors] && valid_methods.any?
65
+ cors = options[:cors].is_a?(Hash) ? otions[:cors] : {origins: options[:cors]}
66
+ enable_cors "#{prefix}#{path}/?:id?#{format}",
67
+ cors.merge(methods: valid_methods)
68
+ end
69
+
70
+ end
71
+
72
+ private
73
+
74
+ def make_path(path)
75
+ path = Hippo.config.api_path + '/' + @ext_id + '/' + path
76
+ Hippo.logger.debug("[route]: #{path}")
77
+ path
78
+ end
79
+ end
80
+
81
+ class RouteSet
82
+ def initialize(root)
83
+ @root = root
84
+ end
85
+
86
+ def draw(&block)
87
+ @root.instance_eval(&block)
88
+ end
89
+
90
+ def for_extension(ext_id, &block)
91
+ routes = RoutingBlock.new(ext_id)
92
+ routes.instance_eval(&block)
93
+ end
94
+ end
95
+
96
+ def self.routes(&block)
97
+ @routes ||= RouteSet.new(API::Root)
98
+ end
99
+
100
+ end
101
+ end
@@ -1,110 +1,21 @@
1
1
  module Hippo
2
2
  module API
3
3
 
4
- def self.set_root_view(view)
5
- API::Root.get Hippo.config.mounted_at + '?*' do
6
- if request.accept? 'text/html'
7
- erb :hippo_root_view
8
- else
9
- pass
10
- end
11
- end
12
- end
13
-
14
- class RoutingBlock
15
- def initialize(ext_id)
16
- Hippo::Extensions.for_identifier(ext_id) ||
17
- raise( "Unable to find extension '#{ext_id}' for screen group")
18
- @ext_id = ext_id
19
- end
20
-
21
- [:get, :post, :put, :patch, :delete].each do | method_name |
22
- define_method(method_name) do | path_suffix, options = {}, &block |
23
- API::Root.send(method_name, make_path(path_suffix), options, &block)
24
- end
25
- end
26
-
27
- def enable_cors(path_suffix, options = {origins: '*', methods: [:get]})
28
- API::Root::CORS_PATHS[make_path(path_suffix)] = options
29
- end
30
-
31
- def resources(model, options = {})
32
- path = options[:path] || model.api_path
33
- controller = options[:controller] || Hippo::API::GenericController
34
- format = options[:format] || '.json'
35
- if options[:under]
36
- options[:parent_attribute] = options[:under].underscore.singularize+'_id'
37
- end
38
-
39
- prefix = options[:parent_attribute] ? options[:parent_attribute] + '/' : ''
40
-
41
- valid_methods = []
42
-
43
- bind = lambda{ |method, route, wrapper_method = method|
44
- valid_methods.push(method)
45
- self.send(method, route + format,
46
- &RequestWrapper.send(wrapper_method, model, controller, options))
47
- }
48
-
49
- # show
50
- if controller.method_defined?(:show)
51
- bind[:get, "#{prefix}#{path}/?:id?"]
52
- end
4
+ module Routing
5
+ mattr_accessor :root_view_route
53
6
 
54
- # create
55
- if controller.method_defined?(:create)
56
- bind[:post, "#{prefix}#{path}"]
7
+ API.routes.draw do
8
+ # WS endpoint must come first
9
+ get Hippo.config.api_path + '/ws' do
10
+ API::Cable.handle_request(request)
57
11
  end
58
12
 
59
- unless options[:immutable]
60
-
61
- # update
62
- if controller.method_defined?(:update)
63
- bind[:patch, "#{prefix}#{path}/?:id?", :update]
64
- bind[:put, "#{prefix}#{path}/?:id?", :update]
65
- end
66
-
67
- # destroy
68
- if controller.method_defined?(:destroy) and not options[:indestructible]
69
- bind[:delete, "#{prefix}#{path}/?:id?"]
70
- end
71
-
72
- end
73
-
74
- if options[:cors] && valid_methods.any?
75
- cors = options[:cors].is_a?(Hash) ? otions[:cors] : {origins: options[:cors]}
76
- enable_cors "#{prefix}#{path}/?:id?#{format}",
77
- cors.merge(methods: valid_methods)
13
+ Extensions.each(reversed: true) do | ext |
14
+ ext.route(self)
78
15
  end
79
-
80
- end
81
-
82
- private
83
-
84
- def make_path(path)
85
- path = Hippo.config.api_path + '/' + @ext_id + '/' + path
86
- Hippo.logger.debug("[route]: #{path}")
87
- path
88
16
  end
89
- end
90
-
91
- class RouteSet
92
- def initialize(root)
93
- @root = root
94
- end
95
-
96
- def draw(&block)
97
- @root.instance_eval(&block)
98
- end
99
-
100
- def for_extension(ext_id, &block)
101
- routes = RoutingBlock.new(ext_id)
102
- routes.instance_eval(&block)
103
- end
104
- end
105
17
 
106
- def self.routes(&block)
107
- @routes ||= RouteSet.new(API::Root)
18
+ root_view_route.call if root_view_route
108
19
  end
109
20
 
110
21
  end