jetski 0.4.8 → 0.4.9
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.
- checksums.yaml +4 -4
- data/bin/jetski +4 -0
- data/bin/jetski_cli_helpers/database.rb +0 -1
- data/bin/jetski_cli_helpers/destroy.rb +4 -9
- data/bin/jetski_cli_helpers/destroyers/controller.rb +18 -0
- data/bin/jetski_cli_helpers/destroyers/model.rb +11 -0
- data/bin/jetski_cli_helpers/generate.rb +11 -40
- data/bin/jetski_cli_helpers/generators/controller.rb +45 -0
- data/bin/jetski_cli_helpers/generators/model.rb +17 -0
- data/lib/jetski/autoloader.rb +1 -1
- data/lib/jetski/base_controller.rb +0 -2
- data/lib/jetski/helpers/route_helpers.rb +0 -1
- data/lib/jetski/helpers/view_helpers.rb +52 -7
- data/lib/jetski/model.rb +13 -1
- data/lib/jetski/router/{shared_methods.rb → file_path_helper.rb} +1 -1
- data/lib/jetski/router/host/base.rb +58 -0
- data/lib/jetski/router/host/controller.rb +57 -0
- data/lib/jetski/router/host/crud.rb +73 -0
- data/lib/jetski/router/parser.rb +7 -7
- data/lib/jetski/router.rb +31 -53
- data/lib/jetski/version.rb +1 -1
- data/lib/jetski/view_renderer.rb +21 -4
- data/lib/jetski.rb +4 -1
- metadata +9 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 147bd3b0e3d8cbbf54b2a4163fe00af53e3941e99942c6d91324e034aaee7f88
|
|
4
|
+
data.tar.gz: 21042af9af87651f01bc4b3b01ed6bb95d45990abcc9ff6fa1bea68b8b38bd68
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 7b045263bc0e38b3e733d0552d7884a5648351a38ba422e8aee9f2604f56d94ef8a9409113aaa377d4828888787587e6b98bc90e6693e7cfcaf63bd5e11a99e6
|
|
7
|
+
data.tar.gz: 6c82897a30e17b21c3b7cb0a626b2cf5240124da8ea197e91c18ff3527e2da93965f456feffcd26c760d40e56534e13c770206de1b712998d2e8c0e4f3496237
|
data/bin/jetski
CHANGED
|
@@ -5,6 +5,10 @@ require 'optparse'
|
|
|
5
5
|
require 'thor'
|
|
6
6
|
require "pry"
|
|
7
7
|
|
|
8
|
+
require_relative './jetski_cli_helpers/generators/controller.rb'
|
|
9
|
+
require_relative './jetski_cli_helpers/generators/model.rb'
|
|
10
|
+
require_relative './jetski_cli_helpers/destroyers/controller.rb'
|
|
11
|
+
require_relative './jetski_cli_helpers/destroyers/model.rb'
|
|
8
12
|
require_relative './jetski_cli_helpers/shared_methods.rb'
|
|
9
13
|
require_relative './jetski_cli_helpers/generate.rb'
|
|
10
14
|
require_relative './jetski_cli_helpers/destroy.rb'
|
|
@@ -1,20 +1,15 @@
|
|
|
1
|
-
require 'thor'
|
|
2
1
|
module JetskiCLIHelpers
|
|
3
2
|
class Destroy < Thor
|
|
4
|
-
include Thor::Actions
|
|
3
|
+
include Thor::Actions, JetskiCLIHelpers::Destroyers::Controller,
|
|
4
|
+
JetskiCLIHelpers::Destroyers::Model
|
|
5
5
|
desc "controller NAME ACTION_NAMES", "Destroys a controller"
|
|
6
6
|
def controller(name, *actions)
|
|
7
|
-
|
|
8
|
-
remove_file(controller_file_path)
|
|
9
|
-
view_folder = "app/views/#{name}"
|
|
10
|
-
remove_dir(view_folder)
|
|
7
|
+
destroy_controller(name)
|
|
11
8
|
end
|
|
12
9
|
|
|
13
10
|
desc "model NAME ACTION_NAMES", "Destroys a model"
|
|
14
11
|
def model(name, *actions)
|
|
15
|
-
|
|
16
|
-
remove_file(controller_file_path)
|
|
17
|
-
# TODO: Remove from db.
|
|
12
|
+
destroy_model(name)
|
|
18
13
|
end
|
|
19
14
|
end
|
|
20
15
|
end
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
module JetskiCLIHelpers
|
|
2
|
+
module Destroyers
|
|
3
|
+
module Controller
|
|
4
|
+
def destroy_controller(name)
|
|
5
|
+
pluralized_name = if name[-1] == 's'
|
|
6
|
+
name
|
|
7
|
+
else
|
|
8
|
+
name + 's'
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
controller_file_path = "app/controllers/#{pluralized_name}_controller.rb"
|
|
12
|
+
remove_file(controller_file_path)
|
|
13
|
+
view_folder = "app/views/#{pluralized_name}"
|
|
14
|
+
remove_dir(view_folder)
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
@@ -1,52 +1,23 @@
|
|
|
1
|
-
require 'thor'
|
|
2
1
|
module JetskiCLIHelpers
|
|
3
2
|
class Generate < Thor
|
|
4
3
|
include Thor::Actions, JetskiCLIHelpers::SharedMethods,
|
|
5
|
-
Jetski::Database::Base
|
|
4
|
+
Jetski::Database::Base, JetskiCLIHelpers::Generators::Controller,
|
|
5
|
+
JetskiCLIHelpers::Generators::Model
|
|
6
6
|
desc "controller NAME ACTION_NAMES", "Create a controller with matching actions"
|
|
7
7
|
def controller(name, *actions)
|
|
8
|
-
|
|
9
|
-
create_file controller_file_path
|
|
10
|
-
append_to_file controller_file_path, <<~CONTROLLER
|
|
11
|
-
class #{name.capitalize}Controller < Jetski::BaseController
|
|
12
|
-
|
|
13
|
-
end
|
|
14
|
-
CONTROLLER
|
|
15
|
-
|
|
16
|
-
actions.each.with_index do |action_name, idx|
|
|
17
|
-
action_content = <<~ACTION_CONTENT
|
|
18
|
-
def #{action_name}
|
|
19
|
-
|
|
20
|
-
end
|
|
21
|
-
ACTION_CONTENT
|
|
22
|
-
action_nl_seperator = ((idx + 1) != actions.size) ? "\n\n" : ""
|
|
23
|
-
insert_into_file(controller_file_path, "#{indent_code(action_content, 1)}#{action_nl_seperator}", before: "\nend")
|
|
24
|
-
|
|
25
|
-
if !["create", "create", "update", "destroy"].include?(action_name)
|
|
26
|
-
path_to_view = "app/views/#{name}/#{action_name}.html.erb"
|
|
27
|
-
|
|
28
|
-
empty_directory("app/views/#{name}")
|
|
29
|
-
create_file(path_to_view)
|
|
30
|
-
append_to_file path_to_view, <<~EXAMPLEFILE
|
|
31
|
-
<h1> #{name}##{action_name} </h1>
|
|
32
|
-
<p> edit the content of this page at app/views/#{path_to_view}/#{action_name}.html.erb </p>
|
|
33
|
-
EXAMPLEFILE
|
|
34
|
-
|
|
35
|
-
say "🌊 View your new page at http://localhost:8000/#{name}/#{action_name}"
|
|
36
|
-
end
|
|
37
|
-
end
|
|
8
|
+
generate_controller(name, *actions)
|
|
38
9
|
end
|
|
39
10
|
|
|
40
11
|
desc "model NAME FIELD_NAMES", "Creates a model with matching fields"
|
|
41
12
|
def model(name, *field_names)
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
13
|
+
generate_model(name, *field_names)
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
desc "resource NAME FIELD_NAMES", "Creates a resource with model and controller and crud routes"
|
|
17
|
+
def resource(name, *field_names)
|
|
18
|
+
crud_actions = %w(new create show index edit update destroy)
|
|
19
|
+
generate_model(name, *field_names)
|
|
20
|
+
generate_controller(name, *crud_actions)
|
|
50
21
|
end
|
|
51
22
|
end
|
|
52
23
|
end
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
module JetskiCLIHelpers
|
|
2
|
+
module Generators
|
|
3
|
+
module Controller
|
|
4
|
+
def generate_controller(name, *actions)
|
|
5
|
+
pluralized_name = if name[-1] == 's'
|
|
6
|
+
name
|
|
7
|
+
else
|
|
8
|
+
name + 's'
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
formatted_controller_name = pluralized_name.split("_").map(&:capitalize).join
|
|
12
|
+
controller_file_path = "app/controllers/#{pluralized_name}_controller.rb"
|
|
13
|
+
create_file controller_file_path
|
|
14
|
+
append_to_file controller_file_path, <<~CONTROLLER
|
|
15
|
+
class #{formatted_controller_name}Controller < Jetski::BaseController
|
|
16
|
+
|
|
17
|
+
end
|
|
18
|
+
CONTROLLER
|
|
19
|
+
|
|
20
|
+
actions.each.with_index do |action_name, idx|
|
|
21
|
+
action_content = <<~ACTION_CONTENT
|
|
22
|
+
def #{action_name}
|
|
23
|
+
|
|
24
|
+
end
|
|
25
|
+
ACTION_CONTENT
|
|
26
|
+
action_nl_seperator = ((idx + 1) != actions.size) ? "\n\n" : ""
|
|
27
|
+
insert_into_file(controller_file_path, "#{indent_code(action_content, 1)}#{action_nl_seperator}", before: "\nend")
|
|
28
|
+
|
|
29
|
+
if !["create", "create", "update", "destroy"].include?(action_name)
|
|
30
|
+
path_to_view = "app/views/#{pluralized_name}/#{action_name}.html.erb"
|
|
31
|
+
|
|
32
|
+
empty_directory("app/views/#{pluralized_name}")
|
|
33
|
+
create_file(path_to_view)
|
|
34
|
+
append_to_file path_to_view, <<~EXAMPLEFILE
|
|
35
|
+
<h1> #{pluralized_name}##{action_name} </h1>
|
|
36
|
+
<p> edit the content of this page at app/views/#{path_to_view}/#{action_name}.html.erb </p>
|
|
37
|
+
EXAMPLEFILE
|
|
38
|
+
|
|
39
|
+
say "🌊 View your new page at http://localhost:8000/#{pluralized_name}/#{action_name}"
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
module JetskiCLIHelpers
|
|
2
|
+
module Generators
|
|
3
|
+
module Model
|
|
4
|
+
def generate_model(name, *field_names)
|
|
5
|
+
db.execute create_table_sql(table_name: name, field_names: field_names)
|
|
6
|
+
model_file_path = "app/models/#{name}.rb"
|
|
7
|
+
create_file model_file_path
|
|
8
|
+
append_to_file model_file_path, <<~MODEL
|
|
9
|
+
class #{name.capitalize} < Jetski::Model
|
|
10
|
+
|
|
11
|
+
end
|
|
12
|
+
MODEL
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
|
data/lib/jetski/autoloader.rb
CHANGED
|
@@ -21,24 +21,60 @@ module Jetski
|
|
|
21
21
|
end
|
|
22
22
|
|
|
23
23
|
# button_to("Click me", class: "cool-btn")
|
|
24
|
-
def button_to(button_text, **html_opts)
|
|
25
|
-
|
|
24
|
+
def button_to(button_text, url = nil, **html_opts)
|
|
25
|
+
if url
|
|
26
|
+
_method = html_opts[:method] || 'POST'
|
|
27
|
+
# Create form with button inside lol
|
|
28
|
+
_form = "<form action='#{url}' method='#{_method}'>"
|
|
29
|
+
_form += "<button type='submit' #{format_html_options(**html_opts)}>#{button_text}</button>"
|
|
30
|
+
_form += "</form>"
|
|
31
|
+
_form
|
|
32
|
+
else
|
|
33
|
+
_button = "<button #{format_html_options(**html_opts)}>#{button_text}</button>"
|
|
34
|
+
end
|
|
26
35
|
end
|
|
27
36
|
|
|
28
|
-
def input_tag(**html_opts)
|
|
37
|
+
def input_tag(input_name = nil, **html_opts)
|
|
38
|
+
html_opts[:name] ||= input_name
|
|
29
39
|
"<input #{format_html_options(**html_opts)}>"
|
|
30
40
|
end
|
|
31
41
|
|
|
32
|
-
def
|
|
33
|
-
"<
|
|
42
|
+
def label_tag(text, **html_opts)
|
|
43
|
+
"<label #{format_html_options(**html_opts)}>#{text}</label>"
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def textarea_tag(name = nil, value = nil, **html_opts)
|
|
47
|
+
html_opts[:name] ||= name
|
|
48
|
+
value ||= html_opts[:value]
|
|
49
|
+
"<textarea #{format_html_options(**html_opts.except(:value))}>#{value}</textarea>"
|
|
34
50
|
end
|
|
35
51
|
|
|
36
52
|
def image_tag(image_path, **html_opts)
|
|
37
|
-
|
|
53
|
+
abs_url = process_url(image_path)
|
|
54
|
+
"<img src='#{abs_url}' #{format_html_options(**html_opts)}></img>"
|
|
38
55
|
end
|
|
39
56
|
|
|
40
57
|
def favicon_tag(url, **html_opts)
|
|
41
|
-
|
|
58
|
+
abs_url = process_url(url)
|
|
59
|
+
"<link rel='icon' type='image/x-icon' #{format_html_options(**html_opts)} href='#{abs_url}'>"
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
def stylesheet_tag(url, **html_opts)
|
|
63
|
+
abs_url = process_url(url)
|
|
64
|
+
"<link rel='stylesheet' #{format_html_options(**html_opts)} href='#{abs_url}'>"
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
def javascript_include_tag(url, **html_opts)
|
|
68
|
+
abs_url = process_url(url)
|
|
69
|
+
"<script src='#{abs_url}' #{format_html_options(**html_opts)}></script>"
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
def javascript_tag(**html_opts)
|
|
73
|
+
"<script #{format_html_options(**html_opts)}>#{yield}</script>"
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
def truncate(text, limit)
|
|
77
|
+
text[0..limit]
|
|
42
78
|
end
|
|
43
79
|
|
|
44
80
|
def format_html_options(**html_opts)
|
|
@@ -47,6 +83,15 @@ module Jetski
|
|
|
47
83
|
"#{formatted_key}='#{v}'"
|
|
48
84
|
end.join(" ")
|
|
49
85
|
end
|
|
86
|
+
private
|
|
87
|
+
def process_url(url)
|
|
88
|
+
# Need to ensure urls start with / to avoid relative requests
|
|
89
|
+
if url[0] == '/'
|
|
90
|
+
url
|
|
91
|
+
else
|
|
92
|
+
"/#{url}"
|
|
93
|
+
end
|
|
94
|
+
end
|
|
50
95
|
end
|
|
51
96
|
end
|
|
52
97
|
end
|
data/lib/jetski/model.rb
CHANGED
|
@@ -27,7 +27,13 @@ module Jetski
|
|
|
27
27
|
end
|
|
28
28
|
|
|
29
29
|
class << self
|
|
30
|
-
def create(**
|
|
30
|
+
def create(hash_args = nil, **key_args)
|
|
31
|
+
args = if hash_args && hash_args.is_a?(Hash)
|
|
32
|
+
hash_args
|
|
33
|
+
else
|
|
34
|
+
key_args
|
|
35
|
+
end
|
|
36
|
+
|
|
31
37
|
return puts "#{table_name.capitalize}.create was called with no args" if args.size == 0
|
|
32
38
|
data_values = args.map { |k,v| v }
|
|
33
39
|
key_names = args.map { |k, v| k }
|
|
@@ -100,6 +106,12 @@ module Jetski
|
|
|
100
106
|
def first
|
|
101
107
|
format_model_obj(pluck_rows.first)
|
|
102
108
|
end
|
|
109
|
+
|
|
110
|
+
def find(id)
|
|
111
|
+
id_as_integer = id.to_i
|
|
112
|
+
columns, *rows = db.execute2( "select * from #{pluralized_table_name} WHERE id=?", id_as_integer)
|
|
113
|
+
format_model_obj(rows.last, columns)
|
|
114
|
+
end
|
|
103
115
|
|
|
104
116
|
def table_name
|
|
105
117
|
self.to_s.downcase
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
module Jetski
|
|
2
|
+
class Router
|
|
3
|
+
module Host
|
|
4
|
+
class Base
|
|
5
|
+
attr_reader :server, :errors, :served_url, :request_method, :req, :res,
|
|
6
|
+
:controller_classname, :controller_file_name, :controller_path,
|
|
7
|
+
:controller_name, :action_name, :controller_class, :all_server_options
|
|
8
|
+
|
|
9
|
+
attr_writer :res, :req
|
|
10
|
+
|
|
11
|
+
def initialize(server, **server_options)
|
|
12
|
+
@server = server
|
|
13
|
+
@errors = []
|
|
14
|
+
@all_server_options = server_options
|
|
15
|
+
@served_url = server_options[:url]
|
|
16
|
+
@request_method = server_options[:method]
|
|
17
|
+
@controller_file_name = server_options[:controller_file_name]
|
|
18
|
+
@controller_path = server_options[:controller_path]
|
|
19
|
+
@controller_classname = server_options[:controller_classname]
|
|
20
|
+
@controller_name = server_options[:controller_name]
|
|
21
|
+
@action_name = server_options[:action_name]
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def call
|
|
25
|
+
server.mount_proc served_url do |req, res|
|
|
26
|
+
@req = req
|
|
27
|
+
@res = res
|
|
28
|
+
check_request_url
|
|
29
|
+
yield
|
|
30
|
+
if errors.any?
|
|
31
|
+
res.body = errors.join(", ")
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
protected
|
|
36
|
+
def fetch_controller_class
|
|
37
|
+
path_to_defined_controller = File.join(Jetski.app_root, "app/controllers/#{controller_file_name}")
|
|
38
|
+
require_relative path_to_defined_controller
|
|
39
|
+
begin
|
|
40
|
+
@controller_class = Object.const_get(controller_classname)
|
|
41
|
+
rescue NameError
|
|
42
|
+
@errors << "#{controller_classname} is not defined. Please create a file app/controllers/#{controller_file_name}"
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
private
|
|
46
|
+
|
|
47
|
+
def check_request_url
|
|
48
|
+
if req.request_uri.path != served_url
|
|
49
|
+
# Silently fail to avoid printing error to page
|
|
50
|
+
res.status = 404
|
|
51
|
+
res.body = "Not Found"
|
|
52
|
+
#@errors << "Wrong url was used for request. Bad url: #{req.request_uri}"
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
end
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
module Jetski
|
|
2
|
+
class Router
|
|
3
|
+
module Host
|
|
4
|
+
class Controller < Base
|
|
5
|
+
# Responsibility is to host the route with methods to route url to controller action
|
|
6
|
+
# URL -> Controller#Action
|
|
7
|
+
# Uses controller class name and action name to serve request
|
|
8
|
+
|
|
9
|
+
def initialize(server, **server_options)
|
|
10
|
+
super(server, **server_options)
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def call
|
|
14
|
+
super do
|
|
15
|
+
fetch_controller_class if errors.empty?
|
|
16
|
+
call_controller if errors.empty?
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def call_controller
|
|
21
|
+
controller = controller_class.new(res)
|
|
22
|
+
controller.action_name = action_name
|
|
23
|
+
controller.controller_name = controller_name
|
|
24
|
+
controller.controller_path = controller_path
|
|
25
|
+
params_hash = {}
|
|
26
|
+
id_crud_actions = ["show", "edit", "destroy"]
|
|
27
|
+
if id_crud_actions.include?(action_name)
|
|
28
|
+
# Need to set id value from url. if available.
|
|
29
|
+
auto_id_param = req.path.split("#{controller_path}/")[-1].split("/")[0]
|
|
30
|
+
params_hash[:id] ||= auto_id_param
|
|
31
|
+
end
|
|
32
|
+
if req.body
|
|
33
|
+
parsed_body = parse_body(req.body, req.content_type)
|
|
34
|
+
params_hash = parsed_body.merge(params_hash)
|
|
35
|
+
end
|
|
36
|
+
controller.params = OpenStruct.new(params_hash)
|
|
37
|
+
controller.cookies = req.cookies
|
|
38
|
+
controller.send(action_name)
|
|
39
|
+
if !controller.performed_render && (request_method.upcase == "GET")
|
|
40
|
+
controller.render
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def parse_body(body, content_type = '')
|
|
45
|
+
case content_type
|
|
46
|
+
when "application/x-www-form-urlencoded"
|
|
47
|
+
Rack::Utils.parse_nested_query body
|
|
48
|
+
when "application/json"
|
|
49
|
+
JSON.parse(body)
|
|
50
|
+
else
|
|
51
|
+
body
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
end
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
module Jetski
|
|
2
|
+
class Router
|
|
3
|
+
module Host
|
|
4
|
+
class Crud < Base
|
|
5
|
+
# Responsible for hosting auto crud routes
|
|
6
|
+
attr_reader :custom_route_options
|
|
7
|
+
attr_accessor :handle_controller_render
|
|
8
|
+
def initialize(server, controller_routes, **server_options)
|
|
9
|
+
server_options[:url] = server_options[:controller_path]
|
|
10
|
+
super(server, **server_options)
|
|
11
|
+
@handle_controller_render = true
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def call
|
|
15
|
+
super do
|
|
16
|
+
@custom_route_options = all_server_options.dup.except(:action_name, :method)
|
|
17
|
+
determine_action_from_url
|
|
18
|
+
if handle_controller_render
|
|
19
|
+
@controller_host = Jetski::Router::Host::Controller.new(server, **custom_route_options)
|
|
20
|
+
@controller_host.res = res
|
|
21
|
+
@controller_host.req = req
|
|
22
|
+
@controller_host.fetch_controller_class
|
|
23
|
+
@controller_host.call_controller
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
private
|
|
28
|
+
def determine_action_from_url
|
|
29
|
+
# TODO: Handle checking for url params.
|
|
30
|
+
req_path = req.request_uri.path
|
|
31
|
+
custom_route_options.tap do |opts|
|
|
32
|
+
case req_path
|
|
33
|
+
when controller_path # /posts
|
|
34
|
+
# check request method for create action
|
|
35
|
+
if req.request_method == "POST"
|
|
36
|
+
opts[:action_name] = "create"
|
|
37
|
+
opts[:method] = "POST"
|
|
38
|
+
else
|
|
39
|
+
opts[:action_name] = "index"
|
|
40
|
+
opts[:method] = "GET"
|
|
41
|
+
end
|
|
42
|
+
when "#{controller_path}/new"
|
|
43
|
+
opts[:action_name] = "new"
|
|
44
|
+
opts[:method] = "GET"
|
|
45
|
+
else
|
|
46
|
+
url_param = req_path.split("#{controller_path}/")[-1]
|
|
47
|
+
case
|
|
48
|
+
when url_param.match(/\d(\/edit)/)
|
|
49
|
+
# Edit page
|
|
50
|
+
opts[:action_name] = "edit"
|
|
51
|
+
opts[:method] = "GET"
|
|
52
|
+
when url_param.match(/\d\z/)
|
|
53
|
+
# matches only id 5 with no additional characters
|
|
54
|
+
# Determine if show/update/destroy from request_method
|
|
55
|
+
opts[:method] = req.request_method
|
|
56
|
+
case req.request_method
|
|
57
|
+
when "GET"
|
|
58
|
+
opts[:action_name] = "show"
|
|
59
|
+
when "PUT"
|
|
60
|
+
opts[:action_name] = "update"
|
|
61
|
+
when "DELETE"
|
|
62
|
+
opts[:action_name] = "destroy"
|
|
63
|
+
end
|
|
64
|
+
else
|
|
65
|
+
handle_controller_render = false
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
end
|
data/lib/jetski/router/parser.rb
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
module Jetski
|
|
2
2
|
class Router
|
|
3
3
|
module Parser
|
|
4
|
-
include Jetski::Router::
|
|
4
|
+
include Jetski::Router::FilePathHelper
|
|
5
5
|
extend self
|
|
6
6
|
def compile_routes
|
|
7
7
|
auto_found_routes = []
|
|
@@ -20,11 +20,11 @@ module Jetski
|
|
|
20
20
|
action_names = controller_class.instance_methods(false)
|
|
21
21
|
base_opts = {
|
|
22
22
|
controller_classname: controller_classname,
|
|
23
|
-
controller_file_name: controller_file_name,
|
|
24
23
|
controller_name: controller_name,
|
|
25
24
|
controller_path: controller_path,
|
|
25
|
+
controller_file_name: controller_file_name,
|
|
26
26
|
}
|
|
27
|
-
route_opts_hash = controller_class.instance_variable_get(:@custom_route_opts)
|
|
27
|
+
route_opts_hash = controller_class.instance_variable_get(:@custom_route_opts) || {}
|
|
28
28
|
action_names.each do |action_name|
|
|
29
29
|
action_name = action_name.to_s
|
|
30
30
|
route_opts = route_opts_hash.fetch(action_name.to_sym, {})
|
|
@@ -41,7 +41,7 @@ module Jetski
|
|
|
41
41
|
url
|
|
42
42
|
end
|
|
43
43
|
end
|
|
44
|
-
|
|
44
|
+
|
|
45
45
|
case action_name
|
|
46
46
|
when "new"
|
|
47
47
|
auto_found_routes << base_opts.merge({
|
|
@@ -51,7 +51,7 @@ module Jetski
|
|
|
51
51
|
})
|
|
52
52
|
when "create"
|
|
53
53
|
auto_found_routes << base_opts.merge({
|
|
54
|
-
url:
|
|
54
|
+
url: controller_path,
|
|
55
55
|
method: "POST",
|
|
56
56
|
action_name: action_name,
|
|
57
57
|
})
|
|
@@ -69,13 +69,13 @@ module Jetski
|
|
|
69
69
|
})
|
|
70
70
|
when "update"
|
|
71
71
|
auto_found_routes << base_opts.merge({
|
|
72
|
-
url:
|
|
72
|
+
url: controller_path + "/:id",
|
|
73
73
|
method: "PUT",
|
|
74
74
|
action_name: action_name,
|
|
75
75
|
})
|
|
76
76
|
when "destroy"
|
|
77
77
|
auto_found_routes << base_opts.merge({
|
|
78
|
-
url:
|
|
78
|
+
url: controller_path + "/:id",
|
|
79
79
|
method: "DELETE",
|
|
80
80
|
action_name: action_name,
|
|
81
81
|
})
|
data/lib/jetski/router.rb
CHANGED
|
@@ -1,60 +1,38 @@
|
|
|
1
1
|
module Jetski
|
|
2
2
|
class Router
|
|
3
3
|
include Parser
|
|
4
|
-
attr_reader :server
|
|
4
|
+
attr_reader :server, :routes, :crud_routes
|
|
5
5
|
def initialize(server)
|
|
6
6
|
@server = server
|
|
7
|
+
@crud_routes = []
|
|
7
8
|
end
|
|
8
9
|
|
|
9
10
|
def call
|
|
10
|
-
|
|
11
|
+
browser_support
|
|
12
|
+
fetch_routes
|
|
13
|
+
host_routes
|
|
14
|
+
host_crud_routes
|
|
15
|
+
host_assets
|
|
11
16
|
end
|
|
12
17
|
|
|
13
18
|
def host_routes
|
|
14
|
-
|
|
19
|
+
crud_actions = %w(new create show index edit update destroy)
|
|
15
20
|
routes.each do |af_route|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
action_name = af_route[:action_name]
|
|
21
|
-
controller_file_name = af_route[:controller_file_name]
|
|
22
|
-
controller_path = af_route[:controller_path]
|
|
23
|
-
|
|
24
|
-
server.mount_proc served_url do |req, res|
|
|
25
|
-
errors = []
|
|
26
|
-
if (request_method!= req.request_method)
|
|
27
|
-
errors << "Wrong request was performed"
|
|
28
|
-
end
|
|
29
|
-
if errors.empty?
|
|
30
|
-
path_to_defined_controller = File.join(Jetski.app_root, "app/controllers/#{controller_file_name}")
|
|
31
|
-
require_relative path_to_defined_controller
|
|
32
|
-
begin
|
|
33
|
-
controller_class = Object.const_get(controller_classname)
|
|
34
|
-
rescue NameError
|
|
35
|
-
errors << "#{controller_classname} is not defined. Please create a file app/controllers/#{controller_file_name}"
|
|
36
|
-
end
|
|
37
|
-
end
|
|
38
|
-
|
|
39
|
-
if errors.empty?
|
|
40
|
-
controller = controller_class.new(res)
|
|
41
|
-
controller.action_name = action_name
|
|
42
|
-
controller.controller_name = controller_name
|
|
43
|
-
controller.controller_path = controller_path
|
|
44
|
-
if req.body
|
|
45
|
-
controller.params = parse_body(req.body, req.content_type)
|
|
46
|
-
end
|
|
47
|
-
controller.cookies = req.cookies
|
|
48
|
-
controller.send(action_name)
|
|
49
|
-
if !controller.performed_render && (request_method.upcase == "GET")
|
|
50
|
-
controller.render
|
|
51
|
-
end
|
|
52
|
-
end
|
|
53
|
-
|
|
54
|
-
if errors.any?
|
|
55
|
-
res.body = errors.join(", ")
|
|
56
|
-
end
|
|
21
|
+
if crud_actions.include?(af_route[:action_name]) && (af_route[:url] != '/')
|
|
22
|
+
@crud_routes << af_route
|
|
23
|
+
next
|
|
24
|
+
# We need to have only one server block for routes with handle crud enabled
|
|
57
25
|
end
|
|
26
|
+
Host::Controller.new(server, **af_route).call
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def host_crud_routes
|
|
31
|
+
# TODO: Build server block to handle custom crud routes
|
|
32
|
+
crud_routes_for_controller = crud_routes.group_by { |route| route[:controller_path] }
|
|
33
|
+
crud_routes_for_controller.each do |controller_path, controller_routes|
|
|
34
|
+
# TODO: Implement base level server block and checking.
|
|
35
|
+
Host::Crud.new(server, controller_routes, **controller_routes.first).call
|
|
58
36
|
end
|
|
59
37
|
end
|
|
60
38
|
|
|
@@ -107,16 +85,16 @@ module Jetski
|
|
|
107
85
|
res.body = File.read(File.join(__dir__, 'frontend/reactive_form.js'))
|
|
108
86
|
end
|
|
109
87
|
end
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
when "application/json"
|
|
116
|
-
OpenStruct.new(JSON.parse(body))
|
|
117
|
-
else
|
|
118
|
-
body
|
|
88
|
+
|
|
89
|
+
# routes to help browser default requests etc. prevent breakage
|
|
90
|
+
def browser_support
|
|
91
|
+
server.mount_proc "/favicon.ico" do |req, res|
|
|
92
|
+
res.status = 204 # No Content
|
|
119
93
|
end
|
|
120
94
|
end
|
|
95
|
+
private
|
|
96
|
+
def fetch_routes
|
|
97
|
+
@routes ||= compile_routes
|
|
98
|
+
end
|
|
121
99
|
end
|
|
122
100
|
end
|
data/lib/jetski/version.rb
CHANGED
data/lib/jetski/view_renderer.rb
CHANGED
|
@@ -13,7 +13,9 @@ module Jetski
|
|
|
13
13
|
|
|
14
14
|
def call
|
|
15
15
|
res.content_type = "text/html"
|
|
16
|
-
|
|
16
|
+
_rendered_view = perform_view_render
|
|
17
|
+
sanitized_view_render = _rendered_view.split("\n").map(&:strip).join("\n")
|
|
18
|
+
view_render = sanitized_view_render.gsub("\n</head>", "#{content_for_head}\n</head>")
|
|
17
19
|
return error_screen if errors.any?
|
|
18
20
|
res.body = view_render
|
|
19
21
|
end
|
|
@@ -24,9 +26,9 @@ module Jetski
|
|
|
24
26
|
end
|
|
25
27
|
|
|
26
28
|
def perform_view_render
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
29
|
+
template_content = File.read(template_path)
|
|
30
|
+
layout_content = File.read(layout_path)
|
|
31
|
+
process_erb(layout_content) { process_erb(template_content) }
|
|
30
32
|
end
|
|
31
33
|
|
|
32
34
|
def process_erb(content)
|
|
@@ -37,6 +39,9 @@ module Jetski
|
|
|
37
39
|
grab_instance_variables
|
|
38
40
|
template.result(binding)
|
|
39
41
|
rescue => e
|
|
42
|
+
# TODO: Add a better error screen like rails show a snapshot of the template and get the line number of error
|
|
43
|
+
# Also using template error doesnt account for errors inside of partials so need a new way of getting this
|
|
44
|
+
@errors << "Error in #{local_template_path}"
|
|
40
45
|
@errors << e
|
|
41
46
|
nil
|
|
42
47
|
end
|
|
@@ -86,6 +91,18 @@ module Jetski
|
|
|
86
91
|
File.join(Jetski.app_root, 'app/assets')
|
|
87
92
|
end
|
|
88
93
|
|
|
94
|
+
def layout_path
|
|
95
|
+
File.join(views_folder, "layouts/application.html.erb")
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
def template_path
|
|
99
|
+
File.join(views_folder, local_template_path)
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
def local_template_path
|
|
103
|
+
File.join(path_to_controller, "#{action_name}.html.erb")
|
|
104
|
+
end
|
|
105
|
+
|
|
89
106
|
def path_to_controller
|
|
90
107
|
controller_path[1..-1]
|
|
91
108
|
end
|
data/lib/jetski.rb
CHANGED
|
@@ -11,8 +11,11 @@ require_relative './jetski/helpers/route_helpers'
|
|
|
11
11
|
require_relative './jetski/helpers/delegatable'
|
|
12
12
|
require_relative './jetski/frontend/reactive_form'
|
|
13
13
|
require_relative './jetski/base_controller'
|
|
14
|
-
require_relative './jetski/router/
|
|
14
|
+
require_relative './jetski/router/file_path_helper'
|
|
15
15
|
require_relative './jetski/router/parser'
|
|
16
|
+
require_relative './jetski/router/host/base'
|
|
17
|
+
require_relative './jetski/router/host/controller'
|
|
18
|
+
require_relative './jetski/router/host/crud'
|
|
16
19
|
require_relative './jetski/router'
|
|
17
20
|
require_relative './jetski/autoloader'
|
|
18
21
|
require_relative './jetski/server'
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: jetski
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.4.
|
|
4
|
+
version: 0.4.9
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Indigo Tech Tutorials
|
|
@@ -118,7 +118,11 @@ files:
|
|
|
118
118
|
- bin/jetski
|
|
119
119
|
- bin/jetski_cli_helpers/database.rb
|
|
120
120
|
- bin/jetski_cli_helpers/destroy.rb
|
|
121
|
+
- bin/jetski_cli_helpers/destroyers/controller.rb
|
|
122
|
+
- bin/jetski_cli_helpers/destroyers/model.rb
|
|
121
123
|
- bin/jetski_cli_helpers/generate.rb
|
|
124
|
+
- bin/jetski_cli_helpers/generators/controller.rb
|
|
125
|
+
- bin/jetski_cli_helpers/generators/model.rb
|
|
122
126
|
- bin/jetski_cli_helpers/shared_methods.rb
|
|
123
127
|
- lib/jetski.rb
|
|
124
128
|
- lib/jetski/autoloader.rb
|
|
@@ -131,8 +135,11 @@ files:
|
|
|
131
135
|
- lib/jetski/helpers/view_helpers.rb
|
|
132
136
|
- lib/jetski/model.rb
|
|
133
137
|
- lib/jetski/router.rb
|
|
138
|
+
- lib/jetski/router/file_path_helper.rb
|
|
139
|
+
- lib/jetski/router/host/base.rb
|
|
140
|
+
- lib/jetski/router/host/controller.rb
|
|
141
|
+
- lib/jetski/router/host/crud.rb
|
|
134
142
|
- lib/jetski/router/parser.rb
|
|
135
|
-
- lib/jetski/router/shared_methods.rb
|
|
136
143
|
- lib/jetski/server.rb
|
|
137
144
|
- lib/jetski/version.rb
|
|
138
145
|
- lib/jetski/view_renderer.rb
|