jetski 0.3.8 → 0.4.1

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 4b9af95cf6ae12478fd887ccfa44148279a237b622b893013d0b93e221f3be73
4
- data.tar.gz: 7f615515947fe954ca0069361cf5eaee12920552028d9e24a3275de2e18713f1
3
+ metadata.gz: a7f1033d352171f7ccf893f673b76ed6f847c404b0aa460812fe60dc4ce0883a
4
+ data.tar.gz: 88b3a07a229f606c2599c6f728423a584b1c242441217f6c04d14c9b1dd8e873
5
5
  SHA512:
6
- metadata.gz: 96d3e3bd8b93a7fa3f52195d0ea5bf6c34435f815e56f0da5e285285cba321de6b8645b3d923740aacd5e42e957158d37ba409bc6b3d9fc770da495d65e6e652
7
- data.tar.gz: de08a81e274f83226cdfb0979656739f6886f04878d87ec5d24e7837d3ef78b6b534569b2dcbee0f826b10de9d994c031c91eb87f86d239128707fbf4d61602e
6
+ metadata.gz: dcce62044cc495b3e39645033c102a5146d39d7a00ecd3dc151d75aed67eda8f0c757323bb426c743cd8873cfa9e33945fbf8881b579853e872a61af524a4473
7
+ data.tar.gz: 2edf2994dd5a44423f48d4a9d2059e6508d2a1f766d0310597ffb7e7e6d975df0fcf0ef66ae6c7168c68e78baa41fc9bd6cfa9d293ce662b4c699909b5039d2a
data/bin/jetski CHANGED
@@ -1,10 +1,16 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
- require 'optparse'
4
3
  require 'jetski'
4
+ require 'optparse'
5
5
  require 'thor'
6
+ require "sqlite3"
7
+ require "pry"
8
+
9
+ require_relative './jetski_cli_helpers/shared_methods.rb'
6
10
  require_relative './jetski_cli_helpers/generate.rb'
7
11
  require_relative './jetski_cli_helpers/destroy.rb'
12
+ require_relative './jetski_cli_helpers/database.rb'
13
+
8
14
  require 'bundler/setup'
9
15
 
10
16
  class JetskiCLI < Thor
@@ -37,15 +43,25 @@ class JetskiCLI < Thor
37
43
 
38
44
  desc "server", "starts the jetski app"
39
45
  def server
40
- ENV['JETSKI_PROJECT_PATH'] = __dir__
41
46
  Jetski::Server.new.call
42
47
  end
43
48
 
49
+ desc "console", "opens jetski console"
50
+ def console
51
+ # TODO: Open console and include all controllers/models/etc
52
+ Jetski::Autoloader.call
53
+ Jetski::Autoloader.load_controllers
54
+ Pry.start
55
+ end
56
+
44
57
  desc "generate", "generates resources in your jetski app"
45
58
  subcommand "generate", JetskiCLIHelpers::Generate
46
59
 
47
60
  desc "destroy", "destroys a resource in your jetski app"
48
61
  subcommand "destroy", JetskiCLIHelpers::Destroy
62
+
63
+ desc "db", "commands related to database"
64
+ subcommand "db", JetskiCLIHelpers::Database
49
65
 
50
66
  def self.source_root
51
67
  File.join(File.dirname(__FILE__), 'templates')
@@ -0,0 +1,27 @@
1
+ require 'thor'
2
+ module JetskiCLIHelpers
3
+ class Database < Thor
4
+ include Thor::Actions, JetskiCLIHelpers::SharedMethods,
5
+ Jetski::Database::Base
6
+ desc "create", "Creates a database for your app"
7
+ def create
8
+ say "🌊 Database was created successfully!"
9
+ end
10
+
11
+ desc "create_table NAME COLUMN_NAMES", "Creates a new table in your database"
12
+ def create_table(name, *fields)
13
+ db.execute create_table_sql(table_name: name, field_names: fields)
14
+ end
15
+
16
+ desc "seed", "Seeds the database with records created from seed file"
17
+ def seed
18
+ seed_file_path = './seed.rb'
19
+ if File.exist?(seed_file_path)
20
+ Jetski::Autoloader.call
21
+ load(seed_file_path)
22
+ else
23
+ say "No seed file is specified create one in your app ./seed.rb"
24
+ end
25
+ end
26
+ end
27
+ end
@@ -9,5 +9,12 @@ module JetskiCLIHelpers
9
9
  view_folder = "app/views/#{name}"
10
10
  remove_dir(view_folder)
11
11
  end
12
+
13
+ desc "model NAME ACTION_NAMES", "Destroys a model"
14
+ def model(name, *actions)
15
+ model_file_path = "app/models/#{name}.rb"
16
+ remove_file(controller_file_path)
17
+ # TODO: Remove from db.
18
+ end
12
19
  end
13
20
  end
@@ -1,31 +1,52 @@
1
1
  require 'thor'
2
2
  module JetskiCLIHelpers
3
3
  class Generate < Thor
4
- include Thor::Actions
4
+ include Thor::Actions, JetskiCLIHelpers::SharedMethods,
5
+ Jetski::Database::Base
5
6
  desc "controller NAME ACTION_NAMES", "Create a controller with matching actions"
6
7
  def controller(name, *actions)
7
8
  controller_file_path = "app/controllers/#{name}_controller.rb"
8
- copy_file("controllers/example_controller", controller_file_path)
9
- gsub_file(controller_file_path, /CONTROLLER_NAME/, name.capitalize)
10
- actions.each.with_index do |action_name, idx|
11
- action_content = "def #{action_name}\n end"
12
- if actions.size < (idx + 1)
13
- action_content += "\nACTION_NAME"
9
+ create_file controller_file_path
10
+ append_to_file controller_file_path, <<~CONTROLLER
11
+ class #{name.capitalize}Controller < Jetski::BaseController
12
+
14
13
  end
15
- gsub_file(controller_file_path, /ACTION_NAME/, action_content.strip)
16
- path_to_view = "app/views/#{name}/#{action_name}.html.erb"
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"
17
27
 
18
- empty_directory("app/views/#{name}")
19
- copy_file("views/example.html.erb", path_to_view)
20
- gsub_file(path_to_view, /CONTROLLER_NAME/, name)
21
- gsub_file(path_to_view, /ACTION_NAME/, action_name)
22
- gsub_file(path_to_view, /PATH_TO_VIEW/, path_to_view)
23
- say "🌊 View your new page at http://localhost:8000/#{name}/#{action_name}"
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
24
37
  end
25
38
  end
26
-
27
- def self.source_root
28
- File.join(File.dirname(__FILE__), '..', 'templates')
39
+
40
+ desc "model NAME FIELD_NAMES", "Creates a model with matching fields"
41
+ def model(name, *field_names)
42
+ db.execute create_table_sql(table_name: name, field_names: field_names)
43
+ model_file_path = "app/models/#{name}.rb"
44
+ create_file model_file_path
45
+ append_to_file model_file_path, <<~MODEL
46
+ class #{name.capitalize} < Jetski::Model
47
+
48
+ end
49
+ MODEL
29
50
  end
30
51
  end
31
52
  end
@@ -0,0 +1,8 @@
1
+ module JetskiCLIHelpers
2
+ module SharedMethods
3
+ def indent_code(code, level = 1)
4
+ code.strip.split("\n").map { |l|
5
+ (1..level).map { |lvl| " " }.join + l }.join("\n")
6
+ end
7
+ end
8
+ end
@@ -0,0 +1 @@
1
+ console.log("🌊 Hello Jetski JS!")
@@ -1,5 +1,5 @@
1
1
  class PagesController < Jetski::BaseController
2
- root
3
2
  def home
3
+ @root = true
4
4
  end
5
5
  end
@@ -4,9 +4,7 @@
4
4
  <meta charset="UTF-8">
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
6
  <title> APP_NAME </title>
7
- <link rel="stylesheet" href="/application.css">
8
7
  <link rel="icon" type="image/x-icon" href="/jetski-logo.png">
9
- DYNAMIC_CSS
10
8
  </head>
11
9
  <body>
12
10
  <%= yield %>
@@ -0,0 +1,18 @@
1
+ module Jetski
2
+ module Autoloader
3
+ include Jetski::Router::SharedMethods
4
+ extend self
5
+ # Responsibility is to load all models in app.
6
+ def call
7
+ model_file_paths.each do |path_to_model|
8
+ require_relative path_to_model
9
+ end
10
+ end
11
+
12
+ def load_controllers
13
+ controller_file_paths.each do |file_path|
14
+ require_relative file_path
15
+ end
16
+ end
17
+ end
18
+ end
@@ -1,23 +1,11 @@
1
1
  # This is the base controller of the library
2
2
  module Jetski
3
3
  class BaseController
4
- attr_accessor :action_name, :controller_name, :controller_path, :params
5
- attr_reader :res
6
- attr_reader :performed_render
7
-
8
- class << self
9
- def request_method(method)
10
- # Really just a shell method since Im using File.readlines to use the logic in routes.
11
- end
12
-
13
- def root
14
- # another shell method
15
- end
16
-
17
- def path(location)
18
- # Another shell method
19
- end
20
- end
4
+ include ReactiveForm
5
+ attr_accessor :action_name, :controller_name, :controller_path,
6
+ :params, :cookies
7
+ attr_reader :res, :performed_render
8
+ attr_writer :root, :path, :request_method
21
9
 
22
10
  def initialize(res)
23
11
  @res = res
@@ -50,25 +38,78 @@ module Jetski
50
38
  res.set_redirect(WEBrick::HTTPStatus::Found, url)
51
39
  end
52
40
 
41
+ def set_cookie(name, value)
42
+ res.cookies.push WEBrick::Cookie.new(name.to_s, value || "")
43
+ end
44
+
45
+ def get_cookie(name)
46
+ cookies&.find { |c| c.name == name.to_s }&.value
47
+ end
48
+
49
+ def is_root?
50
+ @root == true
51
+ end
52
+
53
+ def custom_path
54
+ @path
55
+ end
56
+
57
+ def custom_request_method
58
+ @request_method
59
+ end
60
+
53
61
  private
54
62
  def render_template_file
55
- require 'erb'
56
- views_folder = File.join(Jetski.app_root, 'app/views')
57
- assets_folder = File.join(Jetski.app_root, 'app/assets/stylesheets')
58
- path_to_controller = controller_path[1..-1]
59
- page_with_layout = process_erb(File.read(File.join(views_folder, "layouts/application.html.erb"))) do
63
+ view_render = page_with_layout.gsub("\n</head>", "#{content_for_head}\n</head>")
64
+ res.content_type = "text/html"
65
+ res.body = view_render
66
+ end
67
+
68
+ def page_with_layout
69
+ process_erb(File.read(File.join(views_folder, "layouts/application.html.erb"))) do
60
70
  process_erb(File.read(File.join(views_folder, path_to_controller, "#{action_name}.html.erb")))
61
71
  end
72
+ end
73
+
74
+ def content_for_head
75
+ _content_for_head = ''
62
76
 
63
- action_css_file = File.join(assets_folder, "#{path_to_controller}.css")
64
- css_content = if File.exist? action_css_file
65
- "<link rel='stylesheet' href='/#{path_to_controller}.css'>"
66
- else
67
- ''
77
+ application_css_file = File.join(assets_folder, "stylesheets", "application.css")
78
+ if File.exist? application_css_file
79
+ _content_for_head += "<link rel='stylesheet' href='/application.css'>\n"
68
80
  end
69
- page_with_css = page_with_layout.gsub("DYNAMIC_CSS", css_content)
70
- res.content_type = "text/html"
71
- res.body = page_with_css
81
+
82
+ controller_css_file = File.join(assets_folder, "stylesheets", "#{path_to_controller}.css")
83
+ if File.exist? controller_css_file
84
+ _content_for_head += "<link rel='stylesheet' href='/#{path_to_controller}.css'>\n"
85
+ end
86
+
87
+ application_js_file = File.join(assets_folder, "javascript", "application.js")
88
+ if File.exist? application_js_file
89
+ _content_for_head += "<script src='application.js' defer></script>\n"
90
+ end
91
+
92
+ controller_js_file = File.join(assets_folder, "javascript", "#{path_to_controller}.js")
93
+ if File.exist? controller_js_file
94
+ _content_for_head += "<script src='/#{path_to_controller}.js' defer></script>\n"
95
+ end
96
+
97
+ # Add reactive form JS code
98
+ _content_for_head += "<script src='/reactive-form.js' defer></script>\n"
99
+
100
+ _content_for_head
101
+ end
102
+
103
+ def views_folder
104
+ File.join(Jetski.app_root, 'app/views')
105
+ end
106
+
107
+ def assets_folder
108
+ File.join(Jetski.app_root, 'app/assets')
109
+ end
110
+
111
+ def path_to_controller
112
+ controller_path[1..-1]
72
113
  end
73
114
 
74
115
  def process_erb(content)
@@ -0,0 +1,51 @@
1
+ module Jetski
2
+ module Database
3
+ module Base
4
+ extend self
5
+
6
+ def db
7
+ @_db ||= SQLite3::Database.new "test.db"
8
+ end
9
+
10
+ def create_table_sql(table_name:, field_names:)
11
+ pluralized_table_name = if table_name.chars.last == "s"
12
+ table_name
13
+ else
14
+ table_name + "s"
15
+ end
16
+
17
+ _gen_sql = ""
18
+ _gen_sql += "create table #{pluralized_table_name} (\n"
19
+ _gen_sql += " created_at datetime,\n"
20
+ _gen_sql += " updated_at datetime,\n"
21
+ _gen_sql += " id integer,\n"
22
+
23
+ field_names.each.with_index do |field_name, idx|
24
+ field, field_data_type = if field_name.include?(":")
25
+ field_name.split(":")
26
+ else
27
+ [field_name, ""]
28
+ end
29
+ data_type = sql_data_type(field_data_type)
30
+ _gen_sql += " #{field} #{data_type}"
31
+ if (idx + 1) < field_names.size
32
+ _gen_sql += ",\n"
33
+ else
34
+ _gen_sql += "\n"
35
+ end
36
+ end
37
+ _gen_sql += ");\n"
38
+ _gen_sql
39
+ end
40
+
41
+ def sql_data_type(str)
42
+ case str
43
+ when "", "string"
44
+ "varchar(255)"
45
+ else
46
+ str
47
+ end
48
+ end
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,12 @@
1
+ let reactiveFormELS = document.querySelectorAll("[reactive-form-path]")
2
+ reactiveFormELS.forEach(reactiveFormElement => {
3
+ reactiveFormElement.addEventListener("input", () => {
4
+ let reactiveFormURL = reactiveFormElement.getAttribute("reactive-form-path")
5
+ fetch(reactiveFormURL, {
6
+ body: JSON.stringify({
7
+ content: reactiveFormElement.value,
8
+ }),
9
+ method: "POST",
10
+ })
11
+ })
12
+ })
@@ -0,0 +1,8 @@
1
+ module ReactiveForm
2
+ def reactive_text_area(path, **opts)
3
+ css_classes = opts[:class]
4
+ value = opts[:value]
5
+ # Text area that auto saves to url.
6
+ "<textarea reactive-form-path='#{path}' class='#{css_classes}'>#{value}</textarea>"
7
+ end
8
+ end
@@ -0,0 +1,74 @@
1
+ module Jetski
2
+ class Model
3
+ extend Jetski::Database::Base
4
+ class << self
5
+ def create(**args)
6
+ return puts "#{table_name.capitalize}.create was called with no args" if args.size == 0
7
+ data_values = args.map { |k,v| v }
8
+ key_names = args.map { |k, v| k }
9
+
10
+ key_names.append "created_at"
11
+ data_values.append Time.now.to_s
12
+
13
+ sql_command = <<~SQL
14
+ INSERT INTO #{pluralized_table_name} (#{key_names.join(", ")})
15
+ VALUES (#{(1..key_names.size).map { |n| "?" }.join(", ")})
16
+ SQL
17
+
18
+ db.execute(sql_command, data_values)
19
+ end
20
+
21
+ def all
22
+ columns, *rows = db.execute2( "select * from #{pluralized_table_name}" )
23
+ _all = []
24
+ rows.map do |row|
25
+ _all << format_model_obj(row, columns)
26
+ end
27
+ _all
28
+ end
29
+
30
+ def pluck_rows
31
+ db.execute( "select * from #{pluralized_table_name}" )
32
+ end
33
+
34
+ def count
35
+ pluck_rows.size
36
+ end
37
+
38
+ def attributes
39
+ columns, *rows = db.execute2( "select * from #{pluralized_table_name}" )
40
+ columns
41
+ end
42
+
43
+ def last
44
+ format_model_obj(pluck_rows.last)
45
+ end
46
+
47
+ def first
48
+ format_model_obj(pluck_rows.first)
49
+ end
50
+ private
51
+ def table_name
52
+ self.to_s.downcase
53
+ end
54
+
55
+ def pluralized_table_name
56
+ if table_name[-1] == "s"
57
+ table_name
58
+ else
59
+ table_name + "s"
60
+ end
61
+ end
62
+
63
+ def format_model_obj(row, columns = nil)
64
+ return unless row
65
+ columns ||= attributes
66
+ row_obj = {}
67
+ columns.each.with_index do |col, idx|
68
+ row_obj[col] = row[idx]
69
+ end
70
+ OpenStruct.new(row_obj)
71
+ end
72
+ end
73
+ end
74
+ end
@@ -1,89 +1,88 @@
1
1
  module Jetski
2
2
  class Router
3
3
  module Parser
4
+ include Jetski::Router::SharedMethods
4
5
  extend self
5
6
  def compile_routes
6
7
  auto_found_routes = []
7
- controller_file_paths = Dir.glob([File.join(Jetski.app_root, 'app', 'controllers', '**', '*_controller.rb')])
8
- controller_file_paths.each do |file_path|
8
+ controller_file_paths.each do |file_path|
9
+ require_relative file_path
9
10
  controller_file_name = file_path.split('app/controllers')[1]
10
11
  controller_path = controller_file_name.gsub(/_controller.rb/, '')
11
12
  controller_name = controller_path.split("/").last
12
- controller_classname = controller_path.split("/").reject(&:empty?).map(&:capitalize).join("::") + "Controller"
13
- controller_file_readlines = File.readlines(file_path)
14
- controller_file_readlines.each.with_index do |line, idx|
15
- strp_line = line.strip
16
- if strp_line.start_with?('def')
17
- action_name = strp_line.split("def").last.strip
18
- base_opts = {
19
- controller_classname: controller_classname,
20
- controller_file_name: controller_file_name,
21
- controller_name: controller_name,
22
- controller_path: controller_path,
23
- }
24
- case action_name
25
- when "new"
26
- auto_found_routes << base_opts.merge({
27
- url: controller_path + "/new",
28
- method: "GET",
29
- action_name: action_name,
30
- })
31
- when "create"
32
- auto_found_routes << base_opts.merge({
33
- url: controller_path,
34
- method: "POST",
35
- action_name: action_name,
36
- })
37
- when "show"
38
- auto_found_routes << base_opts.merge({
39
- url: controller_path + "/:id",
40
- method: "GET",
41
- action_name: action_name,
42
- })
43
- when "edit"
44
- auto_found_routes << base_opts.merge({
45
- url: controller_path + "/:id/edit",
46
- method: "GET",
47
- action_name: action_name,
48
- })
49
- when "update"
50
- auto_found_routes << base_opts.merge({
51
- url: controller_path + "/:id",
52
- method: "PUT",
53
- action_name: action_name,
54
- })
55
- when "destroy"
56
- auto_found_routes << base_opts.merge({
57
- url: controller_path + "/:id",
58
- method: "DELETE",
59
- action_name: action_name,
60
- })
13
+ controller_classname = controller_path
14
+ .split("/")
15
+ .reject(&:empty?)
16
+ .map(&:capitalize)
17
+ .map { |c| c.split("_").map(&:capitalize).join }
18
+ .join("::") + "Controller"
19
+ controller_class = Module.const_get(controller_classname)
20
+ action_names = controller_class.instance_methods(false)
21
+ base_opts = {
22
+ controller_classname: controller_classname,
23
+ controller_file_name: controller_file_name,
24
+ controller_name: controller_name,
25
+ controller_path: controller_path,
26
+ }
27
+ action_names.each do |action_name|
28
+ action_name = action_name.to_s
29
+ case action_name
30
+ when "new"
31
+ auto_found_routes << base_opts.merge({
32
+ url: controller_path + "/new",
33
+ method: "GET",
34
+ action_name: action_name,
35
+ })
36
+ when "create"
37
+ auto_found_routes << base_opts.merge({
38
+ url: controller_path,
39
+ method: "POST",
40
+ action_name: action_name,
41
+ })
42
+ when "show"
43
+ auto_found_routes << base_opts.merge({
44
+ url: controller_path + "/:id",
45
+ method: "GET",
46
+ action_name: action_name,
47
+ })
48
+ when "edit"
49
+ auto_found_routes << base_opts.merge({
50
+ url: controller_path + "/:id/edit",
51
+ method: "GET",
52
+ action_name: action_name,
53
+ })
54
+ when "update"
55
+ auto_found_routes << base_opts.merge({
56
+ url: controller_path + "/:id",
57
+ method: "PUT",
58
+ action_name: action_name,
59
+ })
60
+ when "destroy"
61
+ auto_found_routes << base_opts.merge({
62
+ url: controller_path + "/:id",
63
+ method: "DELETE",
64
+ action_name: action_name,
65
+ })
66
+ else
67
+ tmp_controller_instance = controller_class.new("")
68
+ tmp_controller_instance.send(action_name)
69
+ is_root = tmp_controller_instance.is_root?
70
+ custom_path = tmp_controller_instance.custom_path
71
+ url_to_use = if is_root
72
+ "/"
73
+ elsif custom_path
74
+ custom_path
61
75
  else
62
- method_route_options = controller_file_readlines[(idx - 2)..(idx - 1)].map(&:strip)
63
- custom_request_method = method_route_options.find { |line| line.start_with? "request_method" }
64
- custom_request_method = if custom_request_method
65
- custom_request_method.split(" ")[1].gsub('"', '').upcase
66
- else
67
- "GET"
68
- end
69
- custom_path_option = method_route_options.find { |line| line.start_with? "path" }
70
- check_root = controller_file_readlines[idx - 1].strip
71
- url_to_use = if check_root.include?("root")
72
- "/"
73
- else
74
- if custom_path_option
75
- custom_path_option.split(" ")[1].gsub('"', '')
76
- else
77
- url_friendly_action_name = action_name.split("_").join("-")
78
- controller_path + "/#{url_friendly_action_name}"
79
- end
80
- end
81
- auto_found_routes << base_opts.merge({
82
- url: url_to_use,
83
- method: custom_request_method,
84
- action_name: action_name,
85
- })
76
+ url_friendly_action_name = action_name.split("_").join("-")
77
+ controller_path + "/#{url_friendly_action_name}"
86
78
  end
79
+ custom_request_method = tmp_controller_instance.custom_request_method
80
+
81
+ auto_found_routes << base_opts.merge({
82
+ url: url_to_use,
83
+ method: custom_request_method || "GET",
84
+ action_name: action_name,
85
+ })
87
86
  end
88
87
  end
89
88
  end
@@ -0,0 +1,13 @@
1
+ module Jetski
2
+ class Router
3
+ module SharedMethods
4
+ def controller_file_paths
5
+ Dir.glob([File.join(Jetski.app_root, 'app', 'controllers', '**', '*_controller.rb')])
6
+ end
7
+
8
+ def model_file_paths
9
+ Dir.glob(File.join(Jetski.app_root, 'app', 'models', '**/*.rb'))
10
+ end
11
+ end
12
+ end
13
+ end
data/lib/jetski/router.rb CHANGED
@@ -41,7 +41,12 @@ module Jetski
41
41
  controller.action_name = action_name
42
42
  controller.controller_name = controller_name
43
43
  controller.controller_path = controller_path
44
- controller.params = OpenStruct.new(JSON.parse(req.body)) if req.body
44
+ # TODO: Check how body is being passed in and parse it correctly.
45
+ # Currently is breaking with regular html form submissions
46
+ if req.body
47
+ controller.params = parse_body(req.body, req.content_type)
48
+ end
49
+ controller.cookies = req.cookies
45
50
  controller.send(action_name)
46
51
  if !controller.performed_render && (request_method.upcase == "GET")
47
52
  controller.render
@@ -56,8 +61,7 @@ module Jetski
56
61
  end
57
62
 
58
63
  def host_assets
59
- # Render stylesheets css via url
60
- host_css && host_images
64
+ host_css && host_images && host_javascript && host_reactive_form_js
61
65
  end
62
66
 
63
67
  def host_css
@@ -66,14 +70,14 @@ module Jetski
66
70
  filename = file_path.split("app/assets/stylesheets/").last
67
71
  asset_url = "/#{filename}"
68
72
  server.mount_proc asset_url do |req, res|
73
+ res.content_type = "text/css"
69
74
  res.body = File.read(File.join(Jetski.app_root,"app/assets/stylesheets/#{filename}"))
70
75
  end
71
76
  end
72
77
  end
73
78
 
74
79
  def host_images
75
- # TODO: Expand this to support more types of images.
76
- file_ext_types = ["png", "jpg"]
80
+ file_ext_types = ["png", "jpg"] # TODO: Expand this to support more types of images.
77
81
  image_files = Dir.glob(
78
82
  file_ext_types.map { |ext| File.join(Jetski.app_root, "app/assets/images/*.#{ext}") }
79
83
  )
@@ -81,9 +85,40 @@ module Jetski
81
85
  filename = file_path.split("/").last
82
86
  asset_url = "/#{filename}"
83
87
  server.mount_proc asset_url do |req, res|
88
+ res.content_type = "image/*"
84
89
  res.body = File.read(File.join(Jetski.app_root,"app/assets/images/#{filename}"))
85
90
  end
86
91
  end
87
92
  end
93
+
94
+ def host_javascript
95
+ js_files = Dir[File.join(Jetski.app_root,'app/assets/javascript/**/*.js')]
96
+ js_files.each do |file_path|
97
+ filename = file_path.split("app/assets/javascript/").last
98
+ asset_url = "/#{filename}"
99
+ server.mount_proc asset_url do |req, res|
100
+ res.content_type = "text/javascript"
101
+ res.body = File.read(File.join(Jetski.app_root,"app/assets/javascript/#{filename}"))
102
+ end
103
+ end
104
+ end
105
+
106
+ def host_reactive_form_js
107
+ server.mount_proc "/reactive-form.js" do |req, res|
108
+ res.content_type = "text/javascript"
109
+ res.body = File.read(File.join(__dir__, 'frontend/reactive_form.js'))
110
+ end
111
+ end
112
+ private
113
+ def parse_body(body, content_type = '')
114
+ case content_type
115
+ when "application/x-www-form-urlencoded"
116
+ Rack::Utils.parse_nested_query body
117
+ when "application/json"
118
+ OpenStruct.new(JSON.parse(body))
119
+ else
120
+ body
121
+ end
122
+ end
88
123
  end
89
124
  end
data/lib/jetski/server.rb CHANGED
@@ -6,6 +6,8 @@ module Jetski
6
6
  def call
7
7
  server = WEBrick::HTTPServer.new Port: 8000
8
8
 
9
+ Jetski::Autoloader.call
10
+
9
11
  Jetski::Router.new(server).call
10
12
 
11
13
  trap 'INT' do server.shutdown end
@@ -1,3 +1,3 @@
1
1
  module Jetski
2
- VERSION = "0.3.8"
2
+ VERSION = "0.4.1"
3
3
  end
data/lib/jetski.rb CHANGED
@@ -1,16 +1,22 @@
1
- require_relative './jetski/version'
2
- require_relative './jetski/base_controller'
3
- require_relative './jetski/server'
4
- require_relative './jetski/router/parser'
5
- require_relative './jetski/router'
6
1
  require "webrick"
7
2
  require "json"
8
3
  require "json"
9
4
  require "ostruct"
10
5
  require "erb"
6
+ require "rack"
7
+
8
+ require_relative './jetski/version'
9
+ require_relative './jetski/frontend/reactive_form'
10
+ require_relative './jetski/base_controller'
11
+ require_relative './jetski/router/shared_methods'
12
+ require_relative './jetski/router/parser'
13
+ require_relative './jetski/router'
14
+ require_relative './jetski/autoloader'
15
+ require_relative './jetski/server'
16
+ require_relative './jetski/database/base'
17
+ require_relative './jetski/model'
11
18
 
12
19
  module Jetski
13
- # Debug stage add constants here for debugging.
14
20
  extend self
15
21
  def app_root
16
22
  Dir.pwd
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.3.8
4
+ version: 0.4.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Indigo Tech Tutorials
@@ -65,6 +65,48 @@ dependencies:
65
65
  - - "~>"
66
66
  - !ruby/object:Gem::Version
67
67
  version: 5.1.2
68
+ - !ruby/object:Gem::Dependency
69
+ name: sqlite3
70
+ requirement: !ruby/object:Gem::Requirement
71
+ requirements:
72
+ - - "~>"
73
+ - !ruby/object:Gem::Version
74
+ version: 2.8.0
75
+ type: :runtime
76
+ prerelease: false
77
+ version_requirements: !ruby/object:Gem::Requirement
78
+ requirements:
79
+ - - "~>"
80
+ - !ruby/object:Gem::Version
81
+ version: 2.8.0
82
+ - !ruby/object:Gem::Dependency
83
+ name: pry
84
+ requirement: !ruby/object:Gem::Requirement
85
+ requirements:
86
+ - - "~>"
87
+ - !ruby/object:Gem::Version
88
+ version: 0.15.2
89
+ type: :runtime
90
+ prerelease: false
91
+ version_requirements: !ruby/object:Gem::Requirement
92
+ requirements:
93
+ - - "~>"
94
+ - !ruby/object:Gem::Version
95
+ version: 0.15.2
96
+ - !ruby/object:Gem::Dependency
97
+ name: rack
98
+ requirement: !ruby/object:Gem::Requirement
99
+ requirements:
100
+ - - "~>"
101
+ - !ruby/object:Gem::Version
102
+ version: 3.2.4
103
+ type: :runtime
104
+ prerelease: false
105
+ version_requirements: !ruby/object:Gem::Requirement
106
+ requirements:
107
+ - - "~>"
108
+ - !ruby/object:Gem::Version
109
+ version: 3.2.4
68
110
  description: 'Would you rather ride on a train or a jetski? that is the question you
69
111
  might use when comparing using our framework or the popular Ruby on Rails framework. '
70
112
  email: indigo@tech.tut
@@ -74,21 +116,28 @@ extensions: []
74
116
  extra_rdoc_files: []
75
117
  files:
76
118
  - bin/jetski
119
+ - bin/jetski_cli_helpers/database.rb
77
120
  - bin/jetski_cli_helpers/destroy.rb
78
121
  - bin/jetski_cli_helpers/generate.rb
122
+ - bin/jetski_cli_helpers/shared_methods.rb
79
123
  - bin/templates/base/Gemfile
80
124
  - bin/templates/base/app/assets/images/jetski-logo.png
125
+ - bin/templates/base/app/assets/javascript/application.js
81
126
  - bin/templates/base/app/assets/stylesheets/application.css
82
127
  - bin/templates/base/app/assets/stylesheets/pages.css
83
128
  - bin/templates/base/app/controllers/pages_controller.rb
84
129
  - bin/templates/base/app/views/layouts/application.html.erb
85
130
  - bin/templates/base/app/views/pages/home.html.erb
86
- - bin/templates/controllers/example_controller
87
- - bin/templates/views/example.html.erb
88
131
  - lib/jetski.rb
132
+ - lib/jetski/autoloader.rb
89
133
  - lib/jetski/base_controller.rb
134
+ - lib/jetski/database/base.rb
135
+ - lib/jetski/frontend/reactive_form.js
136
+ - lib/jetski/frontend/reactive_form.rb
137
+ - lib/jetski/model.rb
90
138
  - lib/jetski/router.rb
91
139
  - lib/jetski/router/parser.rb
140
+ - lib/jetski/router/shared_methods.rb
92
141
  - lib/jetski/server.rb
93
142
  - lib/jetski/version.rb
94
143
  homepage: https://rubygems.org/gems/jetski
@@ -1,3 +0,0 @@
1
- class CONTROLLER_NAMEController < Jetski::BaseController
2
- ACTION_NAME
3
- end
@@ -1,2 +0,0 @@
1
- <h1> CONTROLLER_NAME#ACTION_NAME </h1>
2
- <p> edit the content of this page at app/views/PATH_TO_VIEW/ACTION_NAME.html.erb </p>