yescode 1.0.0
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 +7 -0
- data/CHANGELOG.md +23 -0
- data/Dockerfile +46 -0
- data/Gemfile +7 -0
- data/LICENSE +21 -0
- data/README.md +73 -0
- data/exe/yescode +16 -0
- data/lib/yes_app.rb +114 -0
- data/lib/yes_controller.rb +85 -0
- data/lib/yes_logger.rb +8 -0
- data/lib/yes_mail.rb +88 -0
- data/lib/yes_rack_logger.rb +59 -0
- data/lib/yes_record.rb +283 -0
- data/lib/yes_routes.rb +64 -0
- data/lib/yes_static.rb +25 -0
- data/lib/yes_view.rb +99 -0
- data/lib/yescode/asset.rb +24 -0
- data/lib/yescode/asset_compiler.rb +33 -0
- data/lib/yescode/assets.rb +30 -0
- data/lib/yescode/database.rb +136 -0
- data/lib/yescode/emote.rb +85 -0
- data/lib/yescode/env.rb +23 -0
- data/lib/yescode/generator.rb +487 -0
- data/lib/yescode/logfmt_formatter.rb +30 -0
- data/lib/yescode/queries.rb +27 -0
- data/lib/yescode/refinements.rb +19 -0
- data/lib/yescode/request_cache/middleware.rb +29 -0
- data/lib/yescode/request_cache.rb +56 -0
- data/lib/yescode/router.rb +78 -0
- data/lib/yescode/strings.rb +23 -0
- data/lib/yescode.rb +48 -0
- data/yescode.gemspec +41 -0
- metadata +161 -0
@@ -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: []
|