wouter 0.0.2 → 0.0.3
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/lib/wouter.rb +100 -67
- metadata +1 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8b80dbc3170d929c2d18d8dfd23513c2e834254de252d50daa55a197e79b3e7c
|
4
|
+
data.tar.gz: 1ff7108b371da999bb465b64a60b8621cba2d1ab90b4943f12eeef58e6e211d1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: df105c88fd3aba2c1747926041f08085f22ea7bfccbc896f35d280b49a578974d4b0e924b6385321cd88d05a931f7c89312cb8cfe2a1f4f002bd79d7bc7e2acb
|
7
|
+
data.tar.gz: fe5583ce266c4c10167e902f221283e37fd54d563f99d165323c9bdedf09e09e101f8f176ec0d9f90686da4a5ed41b245573cb4a9c03cdc202868d793763f0f6
|
data/lib/wouter.rb
CHANGED
@@ -3,53 +3,65 @@ Bundler.setup(:default)
|
|
3
3
|
require "rack"
|
4
4
|
|
5
5
|
class Wouter
|
6
|
+
# ========== Rack wrappers
|
7
|
+
class Request < Rack::Request; end
|
8
|
+
class Response < Rack::Response; end
|
6
9
|
|
7
|
-
#
|
8
|
-
class
|
9
|
-
|
10
|
+
# ========== Endpoint class to make life easier
|
11
|
+
class Endpoint
|
12
|
+
attr_accessor :req, :res
|
10
13
|
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
+
# @req : Request
|
15
|
+
# @res : Response
|
16
|
+
def initialize(req, res)
|
17
|
+
@req = req
|
18
|
+
@res = res
|
19
|
+
end
|
14
20
|
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
21
|
+
def self.call(env)
|
22
|
+
endpoint = new(Rack::Request.new(env), Rack::Response.new)
|
23
|
+
final_resp = endpoint.respond
|
24
|
+
# Return a `Rack::Response` or write to the body of the response if the return value of `response` is not `Rack::Response`
|
25
|
+
if final_resp.is_a?(Rack::Response)
|
26
|
+
final_resp
|
27
|
+
else
|
28
|
+
endpoint.res.write final_resp
|
29
|
+
endpoint.res
|
30
|
+
end
|
31
|
+
end
|
19
32
|
|
20
|
-
|
21
|
-
|
22
|
-
@
|
23
|
-
@params = nil
|
33
|
+
# Users of `Wouter::Endpoint` should implement their own `#response`
|
34
|
+
def respond
|
35
|
+
@res
|
24
36
|
end
|
25
37
|
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
@
|
30
|
-
r = respond
|
31
|
-
@response.write r
|
32
|
-
@response
|
38
|
+
## ~~~~~ Convience methods
|
39
|
+
|
40
|
+
def params
|
41
|
+
@req.params
|
33
42
|
end
|
34
43
|
|
35
44
|
def json(body)
|
36
|
-
@
|
37
|
-
body
|
45
|
+
@res.set_header('Content-Type', 'application/json')
|
46
|
+
@res.write body
|
38
47
|
end
|
39
48
|
|
40
49
|
def status(code)
|
41
|
-
@
|
42
|
-
""
|
50
|
+
@res.status = code
|
43
51
|
end
|
44
52
|
end
|
45
53
|
|
46
|
-
## Internal
|
54
|
+
## ========== Internal
|
55
|
+
|
56
|
+
def self.app
|
57
|
+
@app ||= Rack::Builder.new
|
58
|
+
end
|
47
59
|
|
48
60
|
def self.routes
|
49
61
|
@routes ||= []
|
50
62
|
end
|
51
63
|
|
52
|
-
## DSL
|
64
|
+
## ========== DSL
|
53
65
|
|
54
66
|
class <<self
|
55
67
|
%i[get post put delete].each do |m|
|
@@ -61,61 +73,82 @@ class Wouter
|
|
61
73
|
})
|
62
74
|
end
|
63
75
|
end
|
76
|
+
|
77
|
+
def middleware(klass, *args, &block)
|
78
|
+
app.use(klass, *args, &block)
|
79
|
+
end
|
64
80
|
end
|
65
81
|
|
66
|
-
## Rack
|
82
|
+
## ========== Build a Rack entry point
|
67
83
|
|
68
|
-
def self.
|
69
|
-
|
84
|
+
def self.build
|
85
|
+
app.run(Wrapper.new(routes))
|
86
|
+
app.to_app
|
87
|
+
end
|
70
88
|
|
71
|
-
|
89
|
+
class Wrapper
|
90
|
+
attr_reader :routes
|
72
91
|
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
if
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
route_params[n] = match_data[i+1]
|
87
|
-
end
|
88
|
-
true
|
92
|
+
def initialize(routes)
|
93
|
+
@routes = routes
|
94
|
+
end
|
95
|
+
|
96
|
+
def call(env)
|
97
|
+
request = Rack::Request.new(env)
|
98
|
+
|
99
|
+
route = routes.find do |route|
|
100
|
+
if route[:method] == request.request_method.to_sym
|
101
|
+
if parameterized_path?(route[:path])
|
102
|
+
split_path = route[:path].split("/")
|
103
|
+
path_regex = build_path_regex(split_path)
|
104
|
+
path_regex.match?(request.path)
|
89
105
|
else
|
90
|
-
|
106
|
+
route[:path] == request.path
|
91
107
|
end
|
92
|
-
else
|
93
|
-
route[:path] == request.path
|
94
108
|
end
|
95
109
|
end
|
96
|
-
end
|
97
110
|
|
98
|
-
|
99
|
-
|
100
|
-
|
111
|
+
if route
|
112
|
+
if parameterized_path?(route[:path])
|
113
|
+
split_path = route[:path].split("/")
|
114
|
+
path_parameter_data = build_path_regex(split_path).match(request.path)
|
115
|
+
path_parameter_names = find_parameter_names_in_path(split_path)
|
116
|
+
path_parameter_names.each_with_index do |parameter_name, i|
|
117
|
+
request.update_param(parameter_name, path_parameter_data[i+1])
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
resp = route[:route_class].call(request.env)
|
122
|
+
resp.finish
|
123
|
+
else
|
124
|
+
not_found
|
101
125
|
end
|
126
|
+
end
|
102
127
|
|
103
|
-
|
128
|
+
private
|
104
129
|
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
not_found.finish
|
130
|
+
# Does the path have a parameter in it? ex: "/user/:id"
|
131
|
+
def parameterized_path?(path)
|
132
|
+
path.include?(":")
|
109
133
|
end
|
110
|
-
end
|
111
134
|
|
112
|
-
|
135
|
+
# Find all the named parameters in the route, drop the ":" so we have the names: ":id" => "id"
|
136
|
+
def find_parameter_names_in_path(split_path)
|
137
|
+
split_path.find_all { |s| s.size > 1 ? s[0] == ":" : false }.map { |s| s[1..-1] }
|
138
|
+
end
|
113
139
|
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
end
|
140
|
+
# Turn the route into a regex: "/hello/:name" => "\/hello\/(\w*)"
|
141
|
+
def build_path_regex(split_path)
|
142
|
+
regex_string = split_path.map { |s| s[0] == ":" ? "(\\w*)" : s }.join("\/")
|
143
|
+
Regexp.new(regex_string)
|
144
|
+
end
|
120
145
|
|
146
|
+
# Return HTTP 404
|
147
|
+
def not_found
|
148
|
+
resp = Rack::Response.new
|
149
|
+
resp.status = 404
|
150
|
+
resp.write "Not Found"
|
151
|
+
resp
|
152
|
+
end
|
153
|
+
end
|
121
154
|
end
|