wouter 0.0.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 +7 -0
- data/lib/wouter.rb +156 -0
- metadata +165 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: a103da6e9f11d0e96881ccaf75062ef5a6a5322e78e3010300465645d5a9bd62
|
4
|
+
data.tar.gz: e10e000a61b9a304156429f1c22244ab6af4b456bb17d1960a901eb9c1579a4d
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 3ae45cbb20ba4659e9ef46d44fdb9deafef6fb252ab17acdad3eef68a4a3f446113c2641e672e165d3b9e97cf32d8399932141f4db223a0bbcbfb8f0bcd9c6db
|
7
|
+
data.tar.gz: 95239729b7a893187eb60d126bbd75aab7901718c21e28b47053c491bea3b0eb613539618f2245b69b55cdb4a18a0f3155781179216d173c19f6cd47d2c680f4
|
data/lib/wouter.rb
ADDED
@@ -0,0 +1,156 @@
|
|
1
|
+
require "bundler"
|
2
|
+
Bundler.setup(:default)
|
3
|
+
require "rack"
|
4
|
+
|
5
|
+
class Wouter
|
6
|
+
|
7
|
+
# Incoming HTTP Request Wrapper
|
8
|
+
class Request
|
9
|
+
attr_reader :params
|
10
|
+
|
11
|
+
def initialize(params:)
|
12
|
+
@params = params
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
# Outgoing HTTP Response Wrapper
|
17
|
+
class Response
|
18
|
+
attr_accessor :headers
|
19
|
+
|
20
|
+
def initialize
|
21
|
+
@headers = {'Content-Type' => 'text/html'}
|
22
|
+
@body = ""
|
23
|
+
@status = 200
|
24
|
+
end
|
25
|
+
|
26
|
+
def body(b)
|
27
|
+
@body = b
|
28
|
+
self
|
29
|
+
end
|
30
|
+
|
31
|
+
def status(s)
|
32
|
+
@status = s
|
33
|
+
self
|
34
|
+
end
|
35
|
+
|
36
|
+
def build_response
|
37
|
+
[@status, @headers, [@body]]
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
# HTTP Endpoint Helper class
|
42
|
+
class Endpoint
|
43
|
+
attr_accessor :request, :response
|
44
|
+
attr_reader :params
|
45
|
+
|
46
|
+
def initialize
|
47
|
+
@request = request
|
48
|
+
@response = response
|
49
|
+
end
|
50
|
+
|
51
|
+
def call(req, res)
|
52
|
+
@request = req
|
53
|
+
@params = req.params
|
54
|
+
@response = res
|
55
|
+
r = respond
|
56
|
+
@response.body r
|
57
|
+
end
|
58
|
+
|
59
|
+
def json(body)
|
60
|
+
@response.headers['Content-Type'] = 'application/json'
|
61
|
+
body
|
62
|
+
end
|
63
|
+
|
64
|
+
def status(code)
|
65
|
+
@response.status code
|
66
|
+
""
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
## Route Definitions
|
71
|
+
|
72
|
+
@@routes = []
|
73
|
+
|
74
|
+
## DSL
|
75
|
+
|
76
|
+
class <<self
|
77
|
+
%i[get post put delete].each do |m|
|
78
|
+
define_method(m) do |path, route_class|
|
79
|
+
@@routes.push({
|
80
|
+
method: m.to_s.upcase.to_sym,
|
81
|
+
path: path,
|
82
|
+
route_class: route_class
|
83
|
+
})
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
## Rack API
|
89
|
+
|
90
|
+
def self.call(env)
|
91
|
+
path = env["PATH_INFO"]
|
92
|
+
method = env["REQUEST_METHOD"].to_sym
|
93
|
+
|
94
|
+
route_params = {}
|
95
|
+
|
96
|
+
route = @@routes.find do |route|
|
97
|
+
if route[:method] == method
|
98
|
+
if route[:path].include?(":")
|
99
|
+
split_path = route[:path].split("/")
|
100
|
+
# Find all the named parameters in the route, drop the ":" so we have the names: ":id" => "id"
|
101
|
+
route_param_names = split_path.find_all { |s| s.size > 1 ? s[0] == ":" : false }.map { |s| s[1..-1] }
|
102
|
+
# Turn the route into a regex: "/hello/:name" => "\/hello\/(\w*)"
|
103
|
+
path_regex_string = split_path.map { |s| s[0] == ":" ? "(\\w*)" : s }.join("\/")
|
104
|
+
r = Regexp.new(path_regex_string)
|
105
|
+
if r.match?(path)
|
106
|
+
match_data = r.match(path)
|
107
|
+
# Match the match data with the named params, ex { "id" => 123 }
|
108
|
+
route_param_names.each_with_index do |n, i|
|
109
|
+
route_params[n] = match_data[i+1]
|
110
|
+
end
|
111
|
+
true
|
112
|
+
else
|
113
|
+
false
|
114
|
+
end
|
115
|
+
else
|
116
|
+
route[:path] == path
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
if route
|
122
|
+
params = generate_params(env["rack.input"].gets).merge(route_params)
|
123
|
+
|
124
|
+
request = Request.new(params: params)
|
125
|
+
response = Response.new
|
126
|
+
|
127
|
+
route_response = route[:route_class].new.call(request, response)
|
128
|
+
response route_response
|
129
|
+
else
|
130
|
+
response not_found
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
### Helpers
|
135
|
+
|
136
|
+
def self.not_found
|
137
|
+
resp = Response.new
|
138
|
+
resp.status 404
|
139
|
+
resp.body "Not Found"
|
140
|
+
end
|
141
|
+
|
142
|
+
# Query string comes in as "key=value&key=value" and we turn it into { "key" => "value", "key" => "value" }
|
143
|
+
def self.generate_params(params)
|
144
|
+
return {} if params.nil? || params.empty?
|
145
|
+
params_hash = {}
|
146
|
+
params.split("&").each do |param_pair|
|
147
|
+
key, value = param_pair.split("=")
|
148
|
+
params_hash[key] = value
|
149
|
+
end
|
150
|
+
params_hash
|
151
|
+
end
|
152
|
+
|
153
|
+
def self.response(route_response)
|
154
|
+
route_response.build_response
|
155
|
+
end
|
156
|
+
end
|
metadata
ADDED
@@ -0,0 +1,165 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: wouter
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Robert Peterson
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2018-11-16 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: rack
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '2.0'
|
20
|
+
- - ">="
|
21
|
+
- !ruby/object:Gem::Version
|
22
|
+
version: 2.0.6
|
23
|
+
type: :runtime
|
24
|
+
prerelease: false
|
25
|
+
version_requirements: !ruby/object:Gem::Requirement
|
26
|
+
requirements:
|
27
|
+
- - "~>"
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '2.0'
|
30
|
+
- - ">="
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: 2.0.6
|
33
|
+
- !ruby/object:Gem::Dependency
|
34
|
+
name: rake
|
35
|
+
requirement: !ruby/object:Gem::Requirement
|
36
|
+
requirements:
|
37
|
+
- - "~>"
|
38
|
+
- !ruby/object:Gem::Version
|
39
|
+
version: '12.3'
|
40
|
+
- - ">="
|
41
|
+
- !ruby/object:Gem::Version
|
42
|
+
version: 12.3.1
|
43
|
+
type: :development
|
44
|
+
prerelease: false
|
45
|
+
version_requirements: !ruby/object:Gem::Requirement
|
46
|
+
requirements:
|
47
|
+
- - "~>"
|
48
|
+
- !ruby/object:Gem::Version
|
49
|
+
version: '12.3'
|
50
|
+
- - ">="
|
51
|
+
- !ruby/object:Gem::Version
|
52
|
+
version: 12.3.1
|
53
|
+
- !ruby/object:Gem::Dependency
|
54
|
+
name: rack-test
|
55
|
+
requirement: !ruby/object:Gem::Requirement
|
56
|
+
requirements:
|
57
|
+
- - "~>"
|
58
|
+
- !ruby/object:Gem::Version
|
59
|
+
version: '1.1'
|
60
|
+
- - ">="
|
61
|
+
- !ruby/object:Gem::Version
|
62
|
+
version: 1.1.0
|
63
|
+
type: :development
|
64
|
+
prerelease: false
|
65
|
+
version_requirements: !ruby/object:Gem::Requirement
|
66
|
+
requirements:
|
67
|
+
- - "~>"
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: '1.1'
|
70
|
+
- - ">="
|
71
|
+
- !ruby/object:Gem::Version
|
72
|
+
version: 1.1.0
|
73
|
+
- !ruby/object:Gem::Dependency
|
74
|
+
name: minitest
|
75
|
+
requirement: !ruby/object:Gem::Requirement
|
76
|
+
requirements:
|
77
|
+
- - "~>"
|
78
|
+
- !ruby/object:Gem::Version
|
79
|
+
version: '5.11'
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: 5.11.3
|
83
|
+
type: :development
|
84
|
+
prerelease: false
|
85
|
+
version_requirements: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - "~>"
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '5.11'
|
90
|
+
- - ">="
|
91
|
+
- !ruby/object:Gem::Version
|
92
|
+
version: 5.11.3
|
93
|
+
- !ruby/object:Gem::Dependency
|
94
|
+
name: minitest-rg
|
95
|
+
requirement: !ruby/object:Gem::Requirement
|
96
|
+
requirements:
|
97
|
+
- - "~>"
|
98
|
+
- !ruby/object:Gem::Version
|
99
|
+
version: '5.2'
|
100
|
+
- - ">="
|
101
|
+
- !ruby/object:Gem::Version
|
102
|
+
version: 5.2.0
|
103
|
+
type: :development
|
104
|
+
prerelease: false
|
105
|
+
version_requirements: !ruby/object:Gem::Requirement
|
106
|
+
requirements:
|
107
|
+
- - "~>"
|
108
|
+
- !ruby/object:Gem::Version
|
109
|
+
version: '5.2'
|
110
|
+
- - ">="
|
111
|
+
- !ruby/object:Gem::Version
|
112
|
+
version: 5.2.0
|
113
|
+
- !ruby/object:Gem::Dependency
|
114
|
+
name: m
|
115
|
+
requirement: !ruby/object:Gem::Requirement
|
116
|
+
requirements:
|
117
|
+
- - "~>"
|
118
|
+
- !ruby/object:Gem::Version
|
119
|
+
version: '1.5'
|
120
|
+
- - ">="
|
121
|
+
- !ruby/object:Gem::Version
|
122
|
+
version: 1.5.1
|
123
|
+
type: :development
|
124
|
+
prerelease: false
|
125
|
+
version_requirements: !ruby/object:Gem::Requirement
|
126
|
+
requirements:
|
127
|
+
- - "~>"
|
128
|
+
- !ruby/object:Gem::Version
|
129
|
+
version: '1.5'
|
130
|
+
- - ">="
|
131
|
+
- !ruby/object:Gem::Version
|
132
|
+
version: 1.5.1
|
133
|
+
description: Wouter is a modular web router built on Rack. I like explicitness. I
|
134
|
+
like modularity. Wouter aims to make both of those aspects simple.
|
135
|
+
email: robertpeterson@gmail.com
|
136
|
+
executables: []
|
137
|
+
extensions: []
|
138
|
+
extra_rdoc_files: []
|
139
|
+
files:
|
140
|
+
- lib/wouter.rb
|
141
|
+
homepage: https://github.com/rawburt/wouter
|
142
|
+
licenses:
|
143
|
+
- MIT
|
144
|
+
metadata: {}
|
145
|
+
post_install_message:
|
146
|
+
rdoc_options: []
|
147
|
+
require_paths:
|
148
|
+
- lib
|
149
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
150
|
+
requirements:
|
151
|
+
- - ">="
|
152
|
+
- !ruby/object:Gem::Version
|
153
|
+
version: '0'
|
154
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
155
|
+
requirements:
|
156
|
+
- - ">="
|
157
|
+
- !ruby/object:Gem::Version
|
158
|
+
version: '0'
|
159
|
+
requirements: []
|
160
|
+
rubyforge_project:
|
161
|
+
rubygems_version: 2.7.3
|
162
|
+
signing_key:
|
163
|
+
specification_version: 4
|
164
|
+
summary: Rack web router.
|
165
|
+
test_files: []
|