yescode 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,56 @@
1
+ module Yescode
2
+ module RequestCache
3
+ def self.store
4
+ Thread.current[:request_cache] ||= {}
5
+ end
6
+
7
+ def self.store=(store)
8
+ Thread.current[:request_cache] = store
9
+ end
10
+
11
+ def self.clear!
12
+ Thread.current[:request_cache] = {}
13
+ end
14
+
15
+ def self.begin!
16
+ Thread.current[:request_cache_active] = true
17
+ end
18
+
19
+ def self.end!
20
+ Thread.current[:request_cache_active] = false
21
+ end
22
+
23
+ def self.active?
24
+ Thread.current[:request_cache_active] || false
25
+ end
26
+
27
+ def self.read(key)
28
+ store[key]
29
+ end
30
+
31
+ def self.[](key)
32
+ store[key]
33
+ end
34
+
35
+ def self.write(key, value)
36
+ store[key] = value
37
+ end
38
+
39
+ def self.[]=(key, value)
40
+ store[key] = value
41
+ end
42
+
43
+ def self.exist?(key)
44
+ store.key?(key)
45
+ end
46
+
47
+ def self.fetch(key)
48
+ store[key] = yield unless exist?(key)
49
+ store[key]
50
+ end
51
+
52
+ def self.delete(key, &block)
53
+ store.delete(key, &block)
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,78 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Yescode
4
+ class RouteNotFound < StandardError; end
5
+ class RouteClassDoesNotExist < StandardError; end
6
+ class RouteMethodDoesNotExist < StandardError; end
7
+ class NotFoundError < StandardError; end
8
+ class ServerError < StandardError; end
9
+
10
+ class Router
11
+ using Refinements
12
+
13
+ class << self
14
+ attr_accessor :logger
15
+ end
16
+
17
+ def initialize(app, routes)
18
+ @app = app
19
+ @routes = routes
20
+ @logger = self.class.logger
21
+ end
22
+
23
+ def call(env)
24
+ path_info = env[Rack::PATH_INFO]
25
+ request_method = env[Rack::REQUEST_METHOD]
26
+ params = {}
27
+ route = @routes[request_method].find do |r|
28
+ path = Regexp.new("^#{r.first.gsub(/:(\w+)/, '(?<\1>[a-zA-Z0-9_\-=]+)')}$")
29
+ params = path_info.match(path)&.named_captures
30
+ end
31
+
32
+ raise RouteNotFound unless route
33
+
34
+ params.merge!(env[Rack::RACK_REQUEST_FORM_HASH] || {})
35
+ .transform_keys!(&:to_sym)
36
+ env["params"] = params
37
+ _, class_name, method = route
38
+ klass = nil
39
+ begin
40
+ klass = Object.const_get(class_name)
41
+ rescue NameError => e
42
+ raise RouteClassDoesNotExist, e.message
43
+ end
44
+ obj = klass.new(env)
45
+ raise RouteMethodDoesNotExist, "#{class_name}##{method} does not exist" unless obj.respond_to?(method)
46
+
47
+ @logger&.info(msg: "Request dispatched", route: "#{class_name}##{method}", params: params.except(:_csrf))
48
+ klass.before_actions&.each do |before_action|
49
+ obj.send(before_action)
50
+ end
51
+ response = obj.public_send(method)
52
+ raise NotFoundError if response.nil?
53
+
54
+ case response
55
+ when YesView
56
+ response.csrf_name = obj.csrf_name
57
+ response.csrf_value = obj.csrf_value
58
+ response.assets = @app.assets.to_h
59
+ response.session = obj.session
60
+ response.ajax = env.key?("HTTP_YES_AJAX")
61
+ layout = klass.layout
62
+ content = response.render(response.template)
63
+ content = response.render(layout.template, content:) if layout && response.class < layout.class
64
+ obj.ok content
65
+ else
66
+ response
67
+ end
68
+ rescue NotFoundError, RouteNotFound
69
+ raise if Env.development?
70
+
71
+ [404, { "content-type" => "text/html" }, File.open("public/404.html")]
72
+ rescue StandardError
73
+ raise if Env.development?
74
+
75
+ [500, { "content-type" => "text/html" }, File.open("public/500.html")]
76
+ end
77
+ end
78
+ end
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Yescode
4
+ class Strings
5
+ SNAKE_CASE_REGEX = /\B([A-Z])/
6
+
7
+ class << self
8
+ def snake_case(str)
9
+ str.gsub(SNAKE_CASE_REGEX, '_\1').downcase
10
+ end
11
+
12
+ def camel_case(str)
13
+ return str if !str.include?('_') && str =~ /[A-Z]+.*/
14
+
15
+ str.split('_').map(&:capitalize).join
16
+ end
17
+
18
+ def pascal_case(str)
19
+ camel_case(str).capitalize
20
+ end
21
+ end
22
+ end
23
+ end
data/lib/yescode.rb ADDED
@@ -0,0 +1,48 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "digest"
4
+ require "logger"
5
+ require "net/smtp"
6
+ require "mail"
7
+ require "rack"
8
+ require "rack/csrf"
9
+ require "stringio"
10
+ require "sqlite3"
11
+
12
+ require "yescode/request_cache"
13
+ require "yescode/request_cache/middleware"
14
+ require "yescode/refinements"
15
+ require "yescode/emote"
16
+ require "yescode/strings"
17
+ require "yescode/env"
18
+ require "yescode/logfmt_formatter"
19
+ require "yescode/router"
20
+ require "yescode/database"
21
+ require "yescode/queries"
22
+ require "yescode/assets"
23
+ require "yescode/asset_compiler"
24
+ require "yescode/generator"
25
+
26
+ require "yes_static"
27
+ require "yes_logger"
28
+ require "yes_rack_logger"
29
+ require "yes_routes"
30
+ require "yes_controller"
31
+ require "yes_view"
32
+ require "yes_record"
33
+ require "yes_mail"
34
+ require "yes_app"
35
+
36
+ def require_all(paths)
37
+ paths.each do |path|
38
+ if path.end_with?("*")
39
+ Dir[path].sort.each do |f|
40
+ next unless f.end_with?("rb")
41
+
42
+ require f
43
+ end
44
+ else
45
+ require path
46
+ end
47
+ end
48
+ end
data/yescode.gemspec ADDED
@@ -0,0 +1,41 @@
1
+ # frozen_string_literal: true
2
+
3
+ Gem::Specification.new do |spec|
4
+ spec.platform = Gem::Platform::RUBY
5
+ spec.name = "yescode"
6
+ spec.version = "1.0.0"
7
+ spec.author = "Sean Walker"
8
+ spec.email = "sean@swlkr.com"
9
+
10
+ spec.summary = "A ruby mvc web framework"
11
+ spec.description = "This gem helps you write mvc web applications"
12
+ spec.homepage = "https://github.com/swlkr/yescode"
13
+ spec.license = "MIT"
14
+
15
+ if spec.respond_to?(:metadata)
16
+ spec.metadata["homepage_uri"] = spec.homepage
17
+ spec.metadata["source_code_uri"] = "https://github.com/swlkr/yescode"
18
+ spec.metadata["changelog_uri"] = "https://github.com/swlkr/yescode/blob/main/CHANGELOG.md"
19
+ else
20
+ raise "RubyGems 2.0 or newer is required to protect against " \
21
+ "public gem pushes."
22
+ end
23
+
24
+ # Specify which files should be added to the gem when it is released.
25
+ # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
26
+ spec.files = Dir.chdir(File.expand_path(__dir__)) do
27
+ `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(docs|examples|test|Dockerfile|\.rubocop\.yml|\.solargraph\.yml|\.github)/}) }
28
+ end
29
+ spec.bindir = "exe"
30
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
31
+ spec.require_paths = ["lib"]
32
+ spec.required_ruby_version = ">= 3.1.0"
33
+
34
+ spec.add_development_dependency "minitest", "~> 5.14"
35
+
36
+ spec.add_dependency "mail", "2.7.1"
37
+ spec.add_dependency "net-smtp", "0.3.1"
38
+ spec.add_dependency "rack", "2.2.3"
39
+ spec.add_dependency "rack_csrf", "2.6.0"
40
+ spec.add_dependency "sqlite3", "1.4.2"
41
+ end
metadata ADDED
@@ -0,0 +1,161 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: yescode
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Sean Walker
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2022-05-11 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: minitest
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '5.14'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '5.14'
27
+ - !ruby/object:Gem::Dependency
28
+ name: mail
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - '='
32
+ - !ruby/object:Gem::Version
33
+ version: 2.7.1
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - '='
39
+ - !ruby/object:Gem::Version
40
+ version: 2.7.1
41
+ - !ruby/object:Gem::Dependency
42
+ name: net-smtp
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - '='
46
+ - !ruby/object:Gem::Version
47
+ version: 0.3.1
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - '='
53
+ - !ruby/object:Gem::Version
54
+ version: 0.3.1
55
+ - !ruby/object:Gem::Dependency
56
+ name: rack
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - '='
60
+ - !ruby/object:Gem::Version
61
+ version: 2.2.3
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - '='
67
+ - !ruby/object:Gem::Version
68
+ version: 2.2.3
69
+ - !ruby/object:Gem::Dependency
70
+ name: rack_csrf
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - '='
74
+ - !ruby/object:Gem::Version
75
+ version: 2.6.0
76
+ type: :runtime
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - '='
81
+ - !ruby/object:Gem::Version
82
+ version: 2.6.0
83
+ - !ruby/object:Gem::Dependency
84
+ name: sqlite3
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - '='
88
+ - !ruby/object:Gem::Version
89
+ version: 1.4.2
90
+ type: :runtime
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - '='
95
+ - !ruby/object:Gem::Version
96
+ version: 1.4.2
97
+ description: This gem helps you write mvc web applications
98
+ email: sean@swlkr.com
99
+ executables:
100
+ - yescode
101
+ extensions: []
102
+ extra_rdoc_files: []
103
+ files:
104
+ - CHANGELOG.md
105
+ - Dockerfile
106
+ - Gemfile
107
+ - LICENSE
108
+ - README.md
109
+ - exe/yescode
110
+ - lib/yes_app.rb
111
+ - lib/yes_controller.rb
112
+ - lib/yes_logger.rb
113
+ - lib/yes_mail.rb
114
+ - lib/yes_rack_logger.rb
115
+ - lib/yes_record.rb
116
+ - lib/yes_routes.rb
117
+ - lib/yes_static.rb
118
+ - lib/yes_view.rb
119
+ - lib/yescode.rb
120
+ - lib/yescode/asset.rb
121
+ - lib/yescode/asset_compiler.rb
122
+ - lib/yescode/assets.rb
123
+ - lib/yescode/database.rb
124
+ - lib/yescode/emote.rb
125
+ - lib/yescode/env.rb
126
+ - lib/yescode/generator.rb
127
+ - lib/yescode/logfmt_formatter.rb
128
+ - lib/yescode/queries.rb
129
+ - lib/yescode/refinements.rb
130
+ - lib/yescode/request_cache.rb
131
+ - lib/yescode/request_cache/middleware.rb
132
+ - lib/yescode/router.rb
133
+ - lib/yescode/strings.rb
134
+ - yescode.gemspec
135
+ homepage: https://github.com/swlkr/yescode
136
+ licenses:
137
+ - MIT
138
+ metadata:
139
+ homepage_uri: https://github.com/swlkr/yescode
140
+ source_code_uri: https://github.com/swlkr/yescode
141
+ changelog_uri: https://github.com/swlkr/yescode/blob/main/CHANGELOG.md
142
+ post_install_message:
143
+ rdoc_options: []
144
+ require_paths:
145
+ - lib
146
+ required_ruby_version: !ruby/object:Gem::Requirement
147
+ requirements:
148
+ - - ">="
149
+ - !ruby/object:Gem::Version
150
+ version: 3.1.0
151
+ required_rubygems_version: !ruby/object:Gem::Requirement
152
+ requirements:
153
+ - - ">="
154
+ - !ruby/object:Gem::Version
155
+ version: '0'
156
+ requirements: []
157
+ rubygems_version: 3.3.7
158
+ signing_key:
159
+ specification_version: 4
160
+ summary: A ruby mvc web framework
161
+ test_files: []