kawaii-api 0.0.4
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/LICENSE.txt +22 -0
- data/README.md +215 -0
- data/bin/kawaii-api +6 -0
- data/kawaii.gemspec +30 -0
- data/lib/kawaii.rb +20 -0
- data/lib/kawaii/app.rb +47 -0
- data/lib/kawaii/cli.rb +17 -0
- data/lib/kawaii/controller.rb +9 -0
- data/lib/kawaii/errors.rb +31 -0
- data/lib/kawaii/generators/new_project.rb +75 -0
- data/lib/kawaii/generators/templates/new_project/Gemfile.erb +3 -0
- data/lib/kawaii/generators/templates/new_project/application.rb.erb +10 -0
- data/lib/kawaii/generators/templates/new_project/config.ru.erb +2 -0
- data/lib/kawaii/generators/templates/new_project/routes.rb.erb +3 -0
- data/lib/kawaii/router.rb +34 -0
- data/lib/kawaii/routing/action.rb +22 -0
- data/lib/kawaii/routing/collection.rb +16 -0
- data/lib/kawaii/routing/handler.rb +54 -0
- data/lib/kawaii/routing/member.rb +50 -0
- data/lib/kawaii/routing/namespace.rb +47 -0
- data/lib/kawaii/routing/nested_path.rb +47 -0
- data/lib/kawaii/routing/resource.rb +58 -0
- data/lib/kawaii/routing/resources.rb +23 -0
- data/lib/kawaii/routing/route.rb +23 -0
- data/lib/kawaii/routing/routes.rb +65 -0
- data/lib/kawaii/routing/services/extract_params_from_url.rb +23 -0
- data/lib/kawaii/routing/services/find_controller.rb +48 -0
- data/lib/kawaii/routing/services/generate_resource_actions.rb +53 -0
- data/lib/kawaii/routing/services/generate_resources_actions.rb +35 -0
- data/lib/kawaii/version.rb +3 -0
- metadata +187 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: ea79f9e987e739ff81727f6ce6da51b26a8392e6
|
4
|
+
data.tar.gz: 5e12c43e07da2808b134be8f30fe88d55d7e550c
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 653d5961c1922ca474197408b18bb612b6c559008a6b0114001af1a70e9421614d19fb1d0b81b54b828077f5be9d501a56fc6a35b1d3b97f419dbe7a29551cb6
|
7
|
+
data.tar.gz: 09aee41c9a1ff002e3e2db408004c974e6ded3542bd600bc7a187f580f3bc9211b4ebfae5563f1b6624600bd7b690a6c4e828bd09649a4e2742a4a476ead5419
|
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2016 rybex
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,215 @@
|
|
1
|
+
[](https://travis-ci.org/hanami/hanami)
|
2
|
+
[](https://badge.fury.io/rb/kawaii-api)
|
3
|
+
[](https://codeclimate.com/github/rybex/kawaii)
|
4
|
+
|
5
|
+
# Kawaii
|
6
|
+
|
7
|
+
I would like to share new web API framework based on Rack.
|
8
|
+
|
9
|
+
## Installation
|
10
|
+
|
11
|
+
Add this line to your application's Gemfile:
|
12
|
+
|
13
|
+
```ruby
|
14
|
+
gem 'kawaii-api'
|
15
|
+
```
|
16
|
+
|
17
|
+
And then execute:
|
18
|
+
|
19
|
+
$ bundle
|
20
|
+
|
21
|
+
Or install it yourself as:
|
22
|
+
|
23
|
+
$ gem install kawaii-api
|
24
|
+
|
25
|
+
## Creating new project
|
26
|
+
|
27
|
+
To create new project structure execute:
|
28
|
+
|
29
|
+
$ kawaii-api new app_name
|
30
|
+
|
31
|
+
And then execute:
|
32
|
+
|
33
|
+
$ cd app_name
|
34
|
+
$ bundle install
|
35
|
+
$ rackup
|
36
|
+
|
37
|
+
## Defining routes
|
38
|
+
You can define routes in many ways. All routes have to be defined in class which interhits from `Kawaii::Routing::Routes` class. This is why you can easily split your routes into many files.
|
39
|
+
|
40
|
+
### Support HTTP methods
|
41
|
+
|
42
|
+
```ruby
|
43
|
+
class Routes < Kawaii::Routing::Routes
|
44
|
+
|
45
|
+
#you can specify mapping to controller class
|
46
|
+
get '/kawaii', "controller#method"
|
47
|
+
post '/kawaii', "controller#method"
|
48
|
+
put '/kawaii', "controller#method"
|
49
|
+
delete '/kawaii', "controller#method"
|
50
|
+
|
51
|
+
#or define block as a route handler
|
52
|
+
get '/kawaii' do |params, request|
|
53
|
+
{message: 'Hello'}
|
54
|
+
end
|
55
|
+
post '/kawaii' do |params, request|
|
56
|
+
{message: 'Hello'}
|
57
|
+
end
|
58
|
+
put '/kawaii' do |params, request|
|
59
|
+
{message: 'Hello'}
|
60
|
+
end
|
61
|
+
delete '/kawaii' do |params, request|
|
62
|
+
{message: 'Hello'}
|
63
|
+
end
|
64
|
+
end
|
65
|
+
```
|
66
|
+
|
67
|
+
### REST Resources
|
68
|
+
|
69
|
+
```ruby
|
70
|
+
class Routes < Kawaii::Routing::Routes
|
71
|
+
|
72
|
+
resource :car
|
73
|
+
resources :house
|
74
|
+
end
|
75
|
+
```
|
76
|
+
|
77
|
+
| HTTP_METHOD | PATH | MAPPING |
|
78
|
+
|------------:|-----------|-------------|
|
79
|
+
| :GET | /car | car#index |
|
80
|
+
| :GET | /car/new | car#new |
|
81
|
+
| :POST | /car | car#create |
|
82
|
+
| :GET | /car/edit | car#edit |
|
83
|
+
| :PUT | /car | car#update |
|
84
|
+
| :DELETE | /car | car#destroy |
|
85
|
+
|
86
|
+
```ruby
|
87
|
+
class Routes < Kawaii::Routing::Routes
|
88
|
+
|
89
|
+
resources :car
|
90
|
+
end
|
91
|
+
```
|
92
|
+
|
93
|
+
| HTTP_METHOD | PATH | MAPPING |
|
94
|
+
|------------:|---------------|-------------|
|
95
|
+
| :GET | /car | car#index |
|
96
|
+
| :GET | /car/new | car#new |
|
97
|
+
| :GET | /car/:id | car#show |
|
98
|
+
| :POST | /car | car#create |
|
99
|
+
| :GET | /car/:id/edit | car#edit |
|
100
|
+
| :PUT | /car/:id | car#update |
|
101
|
+
| :DELETE | /car/:id | car#destroy |
|
102
|
+
|
103
|
+
####Nested resources
|
104
|
+
|
105
|
+
```ruby
|
106
|
+
class Routes < Kawaii::Routing::Routes
|
107
|
+
|
108
|
+
resources :cars do
|
109
|
+
resource :wheel
|
110
|
+
end
|
111
|
+
|
112
|
+
resource :human do
|
113
|
+
resources :legs
|
114
|
+
end
|
115
|
+
end
|
116
|
+
```
|
117
|
+
|
118
|
+
####Additional options
|
119
|
+
You can specify which methods do you want to generate.
|
120
|
+
|
121
|
+
```ruby
|
122
|
+
class Routes < Kawaii::Routing::Routes
|
123
|
+
|
124
|
+
resources :cars, [:index, :edit]
|
125
|
+
resource :wheel, [:index]
|
126
|
+
end
|
127
|
+
```
|
128
|
+
|
129
|
+
### Namespaced routes
|
130
|
+
|
131
|
+
```ruby
|
132
|
+
class Routes < Kawaii::Routing::Routes
|
133
|
+
|
134
|
+
namespace :car do
|
135
|
+
resources :wheel
|
136
|
+
|
137
|
+
get :wheel, "controller#method"
|
138
|
+
end
|
139
|
+
end
|
140
|
+
```
|
141
|
+
|
142
|
+
## Creating Controllers
|
143
|
+
App Controllers should be placed in app/ directory. Every controller class must interhits from `Kawaii:Controller` class.
|
144
|
+
|
145
|
+
Let create resource routes.
|
146
|
+
|
147
|
+
```ruby
|
148
|
+
class Routes < Kawaii::Routing::Routes
|
149
|
+
|
150
|
+
resource :car
|
151
|
+
end
|
152
|
+
```
|
153
|
+
|
154
|
+
Then in `app/car_controller.rb` :
|
155
|
+
|
156
|
+
```ruby
|
157
|
+
class CarController < Kawaii::Controller
|
158
|
+
def index
|
159
|
+
end
|
160
|
+
|
161
|
+
def new
|
162
|
+
end
|
163
|
+
|
164
|
+
def create
|
165
|
+
end
|
166
|
+
|
167
|
+
def edit
|
168
|
+
end
|
169
|
+
|
170
|
+
def update
|
171
|
+
end
|
172
|
+
|
173
|
+
def destroy
|
174
|
+
end
|
175
|
+
end
|
176
|
+
```
|
177
|
+
|
178
|
+
## Using Rack middlewares
|
179
|
+
|
180
|
+
```ruby
|
181
|
+
class ModifyResponse
|
182
|
+
def initialize(app)
|
183
|
+
@app = app
|
184
|
+
end
|
185
|
+
attr_reader :app
|
186
|
+
|
187
|
+
def call(env)
|
188
|
+
status, headers, response = app.call(env)
|
189
|
+
response[0] = {message: 'Modified hello'}.to_json
|
190
|
+
[status, headers, response]
|
191
|
+
end
|
192
|
+
end
|
193
|
+
|
194
|
+
class Application < Kawaii::App
|
195
|
+
use ModifyResponse
|
196
|
+
end
|
197
|
+
```
|
198
|
+
|
199
|
+
## Defining custom 404 handler
|
200
|
+
|
201
|
+
```ruby
|
202
|
+
class Application < Kawaii::App
|
203
|
+
route_not_found do
|
204
|
+
[404, {Rack::CONTENT_TYPE => "application/json"}, [{ message: 'Route not exists'}.to_json]]
|
205
|
+
end
|
206
|
+
end
|
207
|
+
```
|
208
|
+
|
209
|
+
## Contributing
|
210
|
+
|
211
|
+
1. Fork it ( https://github.com/[my-github-username]/kawaii/fork )
|
212
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
213
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
214
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
215
|
+
5. Create a new Pull Request
|
data/bin/kawaii-api
ADDED
data/kawaii.gemspec
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'kawaii/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = 'kawaii-api'
|
8
|
+
spec.version = Kawaii::VERSION
|
9
|
+
spec.authors = ['rybex']
|
10
|
+
spec.email = ['tomek.rybka@gmail.com']
|
11
|
+
spec.summary = 'Micro API framework'
|
12
|
+
spec.description = 'Micro API framework to develop web applications in ruby'
|
13
|
+
spec.homepage = 'https://github.com/rybex/kawaii'
|
14
|
+
spec.license = 'MIT'
|
15
|
+
|
16
|
+
spec.files = `git ls-files -z -- lib/* bin/* LICENSE.txt README.md kawaii.gemspec`.split("\x0")
|
17
|
+
spec.executables = ['kawaii-api']
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
+
spec.require_paths = ['lib']
|
20
|
+
|
21
|
+
spec.add_development_dependency 'bundler', '~> 1.7'
|
22
|
+
spec.add_development_dependency 'rake', '~> 10.0'
|
23
|
+
spec.add_development_dependency 'rspec', '~> 3.4.0'
|
24
|
+
spec.add_development_dependency 'pry', '~> 0.10.3'
|
25
|
+
spec.add_development_dependency 'rubocop', '~> 0.40'
|
26
|
+
spec.add_development_dependency 'rack-test', '~> 0.6.3'
|
27
|
+
|
28
|
+
spec.add_runtime_dependency 'rack', '~> 1.6.4'
|
29
|
+
spec.add_runtime_dependency 'thor', '~> 0.19.1'
|
30
|
+
end
|
data/lib/kawaii.rb
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
require 'rack'
|
2
|
+
require 'kawaii/routing/routes'
|
3
|
+
require 'kawaii/routing/handler'
|
4
|
+
require 'kawaii/routing/route'
|
5
|
+
require 'kawaii/routing/namespace'
|
6
|
+
require 'kawaii/routing/nested_path'
|
7
|
+
require 'kawaii/routing/resource'
|
8
|
+
require 'kawaii/routing/resources'
|
9
|
+
require 'kawaii/routing/member'
|
10
|
+
require 'kawaii/routing/collection'
|
11
|
+
require 'kawaii/routing/action'
|
12
|
+
require 'kawaii/routing/services/generate_resource_actions'
|
13
|
+
require 'kawaii/routing/services/generate_resources_actions'
|
14
|
+
require 'kawaii/routing/services/extract_params_from_url'
|
15
|
+
require 'kawaii/routing/services/find_controller'
|
16
|
+
require 'kawaii/app'
|
17
|
+
require 'kawaii/controller'
|
18
|
+
require 'kawaii/version'
|
19
|
+
require 'kawaii/errors'
|
20
|
+
require 'kawaii/router'
|
data/lib/kawaii/app.rb
ADDED
@@ -0,0 +1,47 @@
|
|
1
|
+
module Kawaii
|
2
|
+
class App
|
3
|
+
|
4
|
+
def call(env)
|
5
|
+
self.class.process_request(env)
|
6
|
+
rescue Kawaii::RouteNotFound => error
|
7
|
+
self.class.handle_route_not_found(error)
|
8
|
+
end
|
9
|
+
|
10
|
+
class << self
|
11
|
+
|
12
|
+
def use(middleware, *args, &block)
|
13
|
+
rack_builder.use(middleware, *args, &block)
|
14
|
+
end
|
15
|
+
|
16
|
+
def route_not_found(&block)
|
17
|
+
@exception_handler = block
|
18
|
+
end
|
19
|
+
|
20
|
+
def process_request(env)
|
21
|
+
route = router.match(env)
|
22
|
+
rack_builder.run route.handler
|
23
|
+
handler = rack_builder.to_app
|
24
|
+
handler.call(env)
|
25
|
+
end
|
26
|
+
|
27
|
+
def rack_builder
|
28
|
+
@rack_builder ||= Rack::Builder.new
|
29
|
+
end
|
30
|
+
|
31
|
+
def router
|
32
|
+
@router ||= Router.new
|
33
|
+
end
|
34
|
+
|
35
|
+
def handle_route_not_found(error)
|
36
|
+
handler = @exception_handler || error_handler(error)
|
37
|
+
handler.call(error)
|
38
|
+
end
|
39
|
+
|
40
|
+
private
|
41
|
+
|
42
|
+
def error_handler(error)
|
43
|
+
Proc.new { raise error }
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
data/lib/kawaii/cli.rb
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
require 'thor'
|
2
|
+
|
3
|
+
module Kawaii
|
4
|
+
class CLI < Thor
|
5
|
+
|
6
|
+
desc 'new', 'Create new project structure'
|
7
|
+
def new(name)
|
8
|
+
new_project_generator(name).invoke_all
|
9
|
+
end
|
10
|
+
|
11
|
+
private
|
12
|
+
|
13
|
+
def new_project_generator(name)
|
14
|
+
Generators::NewProject.new([name])
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module Kawaii
|
2
|
+
class MappingAndBlockProvided < StandardError
|
3
|
+
def message
|
4
|
+
'You cant provide mapping and block for route'
|
5
|
+
end
|
6
|
+
end
|
7
|
+
|
8
|
+
class MappingOrBlockMissing < StandardError
|
9
|
+
def message
|
10
|
+
'You must provice block on mapping'
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
class MissingBlockForNamespace < StandardError
|
15
|
+
def message
|
16
|
+
'You must provide block for namespace'
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
class ControllerDoesntExist < StandardError
|
21
|
+
def message
|
22
|
+
'Create controller endpoint for specified route'
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
class RouteNotFound < StandardError
|
27
|
+
def message
|
28
|
+
'Please define route in routes file'
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,75 @@
|
|
1
|
+
require 'thor'
|
2
|
+
|
3
|
+
module Kawaii
|
4
|
+
module Generators
|
5
|
+
class NewProject < Thor::Group
|
6
|
+
include Thor::Actions
|
7
|
+
|
8
|
+
TEMPLATES_DIR = 'templates/new_project'.freeze
|
9
|
+
|
10
|
+
argument :name
|
11
|
+
|
12
|
+
def self.source_root
|
13
|
+
File.dirname(__FILE__)
|
14
|
+
end
|
15
|
+
|
16
|
+
def create_gemfile
|
17
|
+
template(gemfile_template_location, gemfile_file_name)
|
18
|
+
end
|
19
|
+
|
20
|
+
def create_application_rb
|
21
|
+
template(application_template_location, application_file_name)
|
22
|
+
end
|
23
|
+
|
24
|
+
def create_config_ru
|
25
|
+
template(config_ru_template_location, config_ru_file_name)
|
26
|
+
end
|
27
|
+
|
28
|
+
def create_routes_ru
|
29
|
+
template(routes_template_location, routes_file_name)
|
30
|
+
end
|
31
|
+
|
32
|
+
def create_app_folder
|
33
|
+
empty_directory app_file_name
|
34
|
+
end
|
35
|
+
|
36
|
+
private
|
37
|
+
|
38
|
+
def gemfile_template_location
|
39
|
+
"#{TEMPLATES_DIR}/Gemfile.erb"
|
40
|
+
end
|
41
|
+
|
42
|
+
def application_template_location
|
43
|
+
"#{TEMPLATES_DIR}/application.rb.erb"
|
44
|
+
end
|
45
|
+
|
46
|
+
def config_ru_template_location
|
47
|
+
"#{TEMPLATES_DIR}/config.ru.erb"
|
48
|
+
end
|
49
|
+
|
50
|
+
def routes_template_location
|
51
|
+
"#{TEMPLATES_DIR}/routes.rb.erb"
|
52
|
+
end
|
53
|
+
|
54
|
+
def gemfile_file_name
|
55
|
+
"#{name}/Gemfile"
|
56
|
+
end
|
57
|
+
|
58
|
+
def application_file_name
|
59
|
+
"#{name}/application.rb"
|
60
|
+
end
|
61
|
+
|
62
|
+
def config_ru_file_name
|
63
|
+
"#{name}/config.ru"
|
64
|
+
end
|
65
|
+
|
66
|
+
def routes_file_name
|
67
|
+
"#{name}/config/routes.rb"
|
68
|
+
end
|
69
|
+
|
70
|
+
def app_file_name
|
71
|
+
"#{name}/app"
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
module Kawaii
|
2
|
+
class Router
|
3
|
+
def initialize
|
4
|
+
@routes = Routing::Routes.routes
|
5
|
+
end
|
6
|
+
|
7
|
+
def match(env)
|
8
|
+
searched_route = create_route(env)
|
9
|
+
route = find_route(searched_route)
|
10
|
+
raise RouteNotFound unless route
|
11
|
+
route
|
12
|
+
end
|
13
|
+
|
14
|
+
private
|
15
|
+
|
16
|
+
attr_reader :routes
|
17
|
+
|
18
|
+
def find_route(searched_route)
|
19
|
+
routes.detect { |route| route == searched_route }
|
20
|
+
end
|
21
|
+
|
22
|
+
def create_route(env)
|
23
|
+
Routing::Route.new(request_path(env), request_method(env))
|
24
|
+
end
|
25
|
+
|
26
|
+
def request_path(env)
|
27
|
+
env['PATH_INFO']
|
28
|
+
end
|
29
|
+
|
30
|
+
def request_method(env)
|
31
|
+
env['REQUEST_METHOD'].to_sym
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module Kawaii
|
2
|
+
module Routing
|
3
|
+
class Action
|
4
|
+
def initialize(name, http_method, path_pattern, controller_method)
|
5
|
+
@http_method = http_method
|
6
|
+
@path = path_pattern
|
7
|
+
@mapping = generate_mapping(name, controller_method)
|
8
|
+
end
|
9
|
+
attr_reader :http_method, :path, :mapping
|
10
|
+
|
11
|
+
private
|
12
|
+
|
13
|
+
def generate_path(path_pattern, name)
|
14
|
+
path_pattern % [name]
|
15
|
+
end
|
16
|
+
|
17
|
+
def generate_mapping(name, controller_method)
|
18
|
+
"#{name}##{controller_method}"
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module Kawaii
|
2
|
+
module Routing
|
3
|
+
class Collection < Member
|
4
|
+
def initialize(routes, resource, &block)
|
5
|
+
@routes = routes
|
6
|
+
@path = resource_path(resource)
|
7
|
+
@resource = resource
|
8
|
+
instance_eval(&block) if block_given?
|
9
|
+
end
|
10
|
+
|
11
|
+
private
|
12
|
+
|
13
|
+
attr_reader :routes, :path, :parent_name
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
require 'json'
|
2
|
+
|
3
|
+
module Kawaii
|
4
|
+
module Routing
|
5
|
+
class Handler
|
6
|
+
def initialize(path, mapping, block = nil)
|
7
|
+
@path = path
|
8
|
+
@mapping = mapping
|
9
|
+
@handler = block || controller_handler(mapping)
|
10
|
+
end
|
11
|
+
|
12
|
+
def call(env)
|
13
|
+
request = rack_request(env)
|
14
|
+
params = get_url_params(request_path(env))
|
15
|
+
response = call_handler(params, request)
|
16
|
+
format_response(response)
|
17
|
+
end
|
18
|
+
|
19
|
+
private
|
20
|
+
|
21
|
+
attr_reader :path, :mapping, :handler
|
22
|
+
|
23
|
+
def controller_handler(mapping)
|
24
|
+
Kawaii::Routing::Services::FindController.new.call(mapping)
|
25
|
+
end
|
26
|
+
|
27
|
+
def get_url_params(request_url)
|
28
|
+
Kawaii::Routing::Services::ExtractParamsFromUrl.new.call(path, request_url)
|
29
|
+
end
|
30
|
+
|
31
|
+
def rack_request(env)
|
32
|
+
Rack::Request.new(env)
|
33
|
+
end
|
34
|
+
|
35
|
+
def format_response(response)
|
36
|
+
[
|
37
|
+
200,
|
38
|
+
{
|
39
|
+
Rack::CONTENT_TYPE => 'application/json'
|
40
|
+
},
|
41
|
+
[response.to_json]
|
42
|
+
]
|
43
|
+
end
|
44
|
+
|
45
|
+
def call_handler(params, request)
|
46
|
+
handler.call(params, request)
|
47
|
+
end
|
48
|
+
|
49
|
+
def request_path(env)
|
50
|
+
env['PATH_INFO']
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
module Kawaii
|
2
|
+
module Routing
|
3
|
+
class Member
|
4
|
+
def initialize(routes, resource, &block)
|
5
|
+
@routes = routes
|
6
|
+
@path = resource_path(resource)
|
7
|
+
@resource = resource
|
8
|
+
instance_eval(&block) if block_given?
|
9
|
+
end
|
10
|
+
|
11
|
+
def get(action_name)
|
12
|
+
routes.get(member_path(action_name), member_mapping(action_name))
|
13
|
+
end
|
14
|
+
|
15
|
+
def post(action_name)
|
16
|
+
routes.post(member_path(action_name), member_mapping(action_name))
|
17
|
+
end
|
18
|
+
|
19
|
+
def put(action_name)
|
20
|
+
routes.put(member_path(action_name), member_mapping(action_name))
|
21
|
+
end
|
22
|
+
|
23
|
+
def delete(action_name)
|
24
|
+
routes.delete(member_path(action_name), member_mapping(action_name))
|
25
|
+
end
|
26
|
+
|
27
|
+
protected
|
28
|
+
|
29
|
+
def resource_path(resource)
|
30
|
+
NestedPath.new(resource, self.class).path
|
31
|
+
end
|
32
|
+
|
33
|
+
def resource_name
|
34
|
+
resource.resource_name
|
35
|
+
end
|
36
|
+
|
37
|
+
def member_path(action_name)
|
38
|
+
"#{path}/#{action_name}"
|
39
|
+
end
|
40
|
+
|
41
|
+
def member_mapping(action_name)
|
42
|
+
"#{resource_name}##{action_name}"
|
43
|
+
end
|
44
|
+
|
45
|
+
private
|
46
|
+
|
47
|
+
attr_reader :routes, :path, :resource
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
module Kawaii
|
2
|
+
module Routing
|
3
|
+
class Namespace
|
4
|
+
def initialize(routes, namespace_name, &block)
|
5
|
+
@routes = routes
|
6
|
+
@namespace_name = namespace_name
|
7
|
+
instance_eval(&block) if block_given?
|
8
|
+
end
|
9
|
+
|
10
|
+
def get(path, mapping)
|
11
|
+
routes.get(namespace_path(path), wrap_in_namespace(mapping))
|
12
|
+
end
|
13
|
+
|
14
|
+
def post(path, mapping)
|
15
|
+
routes.post(namespace_path(path), wrap_in_namespace(mapping))
|
16
|
+
end
|
17
|
+
|
18
|
+
def put(path, mapping)
|
19
|
+
routes.put(namespace_path(path), wrap_in_namespace(mapping))
|
20
|
+
end
|
21
|
+
|
22
|
+
def delete(path, mapping)
|
23
|
+
routes.delete(namespace_path(path), wrap_in_namespace(mapping))
|
24
|
+
end
|
25
|
+
|
26
|
+
def resource(resource_name, methods = nil, &block)
|
27
|
+
Resource.new(routes, resource_name, methods, namespace_name, &block)
|
28
|
+
end
|
29
|
+
|
30
|
+
def resources(resources_name, methods = nil, &block)
|
31
|
+
Resources.new(routes, resources_name, methods, namespace_name, &block)
|
32
|
+
end
|
33
|
+
|
34
|
+
private
|
35
|
+
|
36
|
+
attr_reader :routes, :namespace_name
|
37
|
+
|
38
|
+
def namespace_path(path)
|
39
|
+
"/#{namespace_name}/#{path}"
|
40
|
+
end
|
41
|
+
|
42
|
+
def wrap_in_namespace(mapping)
|
43
|
+
"#{namespace_name}/#{mapping}"
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
module Kawaii
|
2
|
+
module Routing
|
3
|
+
class NestedPath
|
4
|
+
def initialize(resource, action_class = nil)
|
5
|
+
@resource = resource
|
6
|
+
@action_class = action_class
|
7
|
+
@path = wrap_namespace(resource, calculate(resource))
|
8
|
+
end
|
9
|
+
attr_reader :resource, :path, :action_class
|
10
|
+
|
11
|
+
private
|
12
|
+
|
13
|
+
def calculate(nested = nil, path = nil)
|
14
|
+
unless path
|
15
|
+
path = init_path
|
16
|
+
else
|
17
|
+
path.prepend nested.resource_path
|
18
|
+
end
|
19
|
+
calculate(nested.parent, path) if nested.parent
|
20
|
+
path
|
21
|
+
end
|
22
|
+
|
23
|
+
def init_path
|
24
|
+
if resource.class == Resources && action_class == Member
|
25
|
+
resource_path
|
26
|
+
else
|
27
|
+
resource_name
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def resource_name
|
32
|
+
"/#{resource.name}"
|
33
|
+
end
|
34
|
+
|
35
|
+
def resource_path
|
36
|
+
resource.resource_path
|
37
|
+
end
|
38
|
+
|
39
|
+
def wrap_namespace(nested, path)
|
40
|
+
if nested.namespace
|
41
|
+
path.prepend "/#{nested.namespace}"
|
42
|
+
end
|
43
|
+
path
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
module Kawaii
|
2
|
+
module Routing
|
3
|
+
class Resource
|
4
|
+
METHODS = [:index, :new, :create, :edit, :update, :destroy].freeze
|
5
|
+
|
6
|
+
def initialize(routes, name, methods, namespace = nil, parent = nil, &block)
|
7
|
+
@routes = routes
|
8
|
+
@name = name
|
9
|
+
@parent = parent
|
10
|
+
@methods = methods || METHODS
|
11
|
+
@namespace = namespace
|
12
|
+
@actions_generator = Services::GenerateResourceActions
|
13
|
+
generate_actions
|
14
|
+
instance_eval(&block) if block_given?
|
15
|
+
end
|
16
|
+
attr_reader :routes, :name, :parent, :namespace, :actions_generator
|
17
|
+
|
18
|
+
def member(&block)
|
19
|
+
Member.new(routes, self, &block)
|
20
|
+
end
|
21
|
+
|
22
|
+
def collection(&block)
|
23
|
+
Collection.new(routes, self, &block)
|
24
|
+
end
|
25
|
+
|
26
|
+
def resource(resource_name, methods = nil, &block)
|
27
|
+
Resource.new(routes, resource_name, methods, namespace, self, &block)
|
28
|
+
end
|
29
|
+
|
30
|
+
def resources(resources_name, methods = nil, &block)
|
31
|
+
Resources.new(routes, resources_name, methods, namespace, self, &block)
|
32
|
+
end
|
33
|
+
|
34
|
+
def resource_path
|
35
|
+
"/#{name}"
|
36
|
+
end
|
37
|
+
|
38
|
+
def resource_name
|
39
|
+
resource_name = name.to_s
|
40
|
+
resource_name.prepend "#{namespace}/" if namespace
|
41
|
+
resource_name
|
42
|
+
end
|
43
|
+
|
44
|
+
protected
|
45
|
+
|
46
|
+
def resource_full_path
|
47
|
+
NestedPath.new(self).path
|
48
|
+
end
|
49
|
+
|
50
|
+
def generate_actions
|
51
|
+
actions = actions_generator.new(resource_name, resource_full_path, @methods).call
|
52
|
+
actions.each do |action|
|
53
|
+
routes.send(action.http_method, action.path, action.mapping)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module Kawaii
|
2
|
+
module Routing
|
3
|
+
class Resources < Resource
|
4
|
+
METHODS = [:index, :new, :show, :create, :edit, :update, :destroy].freeze
|
5
|
+
|
6
|
+
def initialize(routes, name, methods, namespace = nil, parent = nil, &block)
|
7
|
+
@routes = routes
|
8
|
+
@name = name
|
9
|
+
@parent = parent
|
10
|
+
@methods = methods || METHODS
|
11
|
+
@namespace = namespace
|
12
|
+
@actions_generator = Services::GenerateResourcesActions
|
13
|
+
generate_actions
|
14
|
+
instance_eval(&block) if block_given?
|
15
|
+
end
|
16
|
+
attr_reader :routes, :name, :parent, :namespace, :actions_generator
|
17
|
+
|
18
|
+
def resource_path
|
19
|
+
"/#{name}/:#{name.to_s.split('/').last}_id"
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module Kawaii
|
2
|
+
module Routing
|
3
|
+
class Route
|
4
|
+
def initialize(path, http_method, mapping = nil, block = nil)
|
5
|
+
@path = path
|
6
|
+
@http_method = http_method
|
7
|
+
@mapping = mapping
|
8
|
+
@handler = route_handler(path, mapping, block)
|
9
|
+
end
|
10
|
+
attr_reader :path, :mapping, :handler, :http_method
|
11
|
+
|
12
|
+
def ==(other)
|
13
|
+
path == other.path && http_method == other.http_method
|
14
|
+
end
|
15
|
+
|
16
|
+
private
|
17
|
+
|
18
|
+
def route_handler(path, mapping, block)
|
19
|
+
Handler.new(path, mapping, block) if mapping || block
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,65 @@
|
|
1
|
+
module Kawaii
|
2
|
+
module Routing
|
3
|
+
class Routes
|
4
|
+
@@routes ||= []
|
5
|
+
|
6
|
+
class << self
|
7
|
+
def get(path, mapping = nil, &block)
|
8
|
+
create_route(path, mapping, :GET, block)
|
9
|
+
end
|
10
|
+
|
11
|
+
def post(path, mapping = nil, &block)
|
12
|
+
create_route(path, mapping, :POST, block)
|
13
|
+
end
|
14
|
+
|
15
|
+
def put(path, mapping = nil, &block)
|
16
|
+
create_route(path, mapping, :PUT, block)
|
17
|
+
end
|
18
|
+
|
19
|
+
def delete(path, mapping = nil, &block)
|
20
|
+
create_route(path, mapping, :DELETE, block)
|
21
|
+
end
|
22
|
+
|
23
|
+
def resources(name, methods = nil, &block)
|
24
|
+
Resources.new(self, name, methods, &block)
|
25
|
+
end
|
26
|
+
|
27
|
+
def resource(name, methods = nil, &block)
|
28
|
+
Resource.new(self, name, methods, &block)
|
29
|
+
end
|
30
|
+
|
31
|
+
def namespace(name, &block)
|
32
|
+
Namespace.new(self, name, &block)
|
33
|
+
end
|
34
|
+
|
35
|
+
def routes
|
36
|
+
@@routes
|
37
|
+
end
|
38
|
+
|
39
|
+
def reset
|
40
|
+
@@routes = []
|
41
|
+
end
|
42
|
+
|
43
|
+
private
|
44
|
+
|
45
|
+
def create_route(path, mapping, http_method, block)
|
46
|
+
validate_arguments(mapping, block)
|
47
|
+
add_route_to_list(route(path, mapping, http_method, block))
|
48
|
+
end
|
49
|
+
|
50
|
+
def validate_arguments(mapping, block)
|
51
|
+
raise MappingAndBlockProvided if mapping && block
|
52
|
+
raise MappingOrBlockMissing unless mapping || block
|
53
|
+
end
|
54
|
+
|
55
|
+
def add_route_to_list(route)
|
56
|
+
@@routes.push(route)
|
57
|
+
end
|
58
|
+
|
59
|
+
def route(path, mapping, http_method, block)
|
60
|
+
Route.new(path, http_method, mapping, block)
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module Kawaii
|
2
|
+
module Routing
|
3
|
+
module Services
|
4
|
+
class ExtractParamsFromUrl
|
5
|
+
def call(path_pattern, url)
|
6
|
+
regexp = pattern_to_regexp(path_pattern)
|
7
|
+
matches = regexp.match(url)
|
8
|
+
format_to_hash(matches)
|
9
|
+
end
|
10
|
+
|
11
|
+
private
|
12
|
+
|
13
|
+
def format_to_hash(matches)
|
14
|
+
Hash[matches.names.zip(matches[1..-1])]
|
15
|
+
end
|
16
|
+
|
17
|
+
def pattern_to_regexp(pattern)
|
18
|
+
Regexp.new(Regexp.escape(pattern).gsub(/:(\w+)/, '(?<\1>.+?)'))
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
module Kawaii
|
2
|
+
module Routing
|
3
|
+
module Services
|
4
|
+
class FindController
|
5
|
+
def call(mapping)
|
6
|
+
controller_name, method = parse_mapping(mapping)
|
7
|
+
controller_class = find_controller(controller_name)
|
8
|
+
proc do |params, request|
|
9
|
+
raise ControllerDoesntExist if controller_class.nil?
|
10
|
+
controller = controller_class.new(params, request)
|
11
|
+
controller.send(method)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
private
|
16
|
+
|
17
|
+
def find_controller(controller_name)
|
18
|
+
Object.const_get(controller_name)
|
19
|
+
rescue
|
20
|
+
nil
|
21
|
+
end
|
22
|
+
|
23
|
+
def parse_mapping(mapping)
|
24
|
+
mapping_with_namespace = mapping.split('/')
|
25
|
+
namespace = mapping_with_namespace[0] if mapping_with_namespace.length > 1
|
26
|
+
controller, method = mapping_with_namespace.last.split('#')
|
27
|
+
[get_controller(namespace, controller), method.to_sym]
|
28
|
+
end
|
29
|
+
|
30
|
+
def get_controller(namespace, controller)
|
31
|
+
controller_name = controller_name(controller)
|
32
|
+
if namespace
|
33
|
+
controller_name = wrap_namespace(namespace, controller_name)
|
34
|
+
end
|
35
|
+
controller_name
|
36
|
+
end
|
37
|
+
|
38
|
+
def controller_name(controller)
|
39
|
+
"#{controller.capitalize}Controller"
|
40
|
+
end
|
41
|
+
|
42
|
+
def wrap_namespace(namespace, controller_name)
|
43
|
+
"#{namespace.capitalize}::#{controller_name}"
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
module Kawaii
|
2
|
+
module Routing
|
3
|
+
module Services
|
4
|
+
class GenerateResourceActions
|
5
|
+
def initialize(name, path, methods)
|
6
|
+
@name = name.to_s
|
7
|
+
@methods = methods
|
8
|
+
@path = path
|
9
|
+
end
|
10
|
+
|
11
|
+
def call
|
12
|
+
methods.map do |method|
|
13
|
+
send(method)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
protected
|
18
|
+
|
19
|
+
def index
|
20
|
+
get_action(name, :get, path.to_s, 'index')
|
21
|
+
end
|
22
|
+
|
23
|
+
def new
|
24
|
+
get_action(name, :get, "#{path}/new", 'new')
|
25
|
+
end
|
26
|
+
|
27
|
+
def edit
|
28
|
+
get_action(name, :get, "#{path}/edit", 'edit')
|
29
|
+
end
|
30
|
+
|
31
|
+
def create
|
32
|
+
get_action(name, :post, path.to_s, 'create')
|
33
|
+
end
|
34
|
+
|
35
|
+
def update
|
36
|
+
get_action(name, :put, path.to_s, 'update')
|
37
|
+
end
|
38
|
+
|
39
|
+
def destroy
|
40
|
+
get_action(name, :delete, path.to_s, 'destroy')
|
41
|
+
end
|
42
|
+
|
43
|
+
def get_action(name, http_method, path_pattern, controller_method)
|
44
|
+
Routing::Action.new(name, http_method, path_pattern, controller_method)
|
45
|
+
end
|
46
|
+
|
47
|
+
private
|
48
|
+
|
49
|
+
attr_reader :methods, :name, :path
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
module Kawaii
|
2
|
+
module Routing
|
3
|
+
module Services
|
4
|
+
class GenerateResourcesActions < GenerateResourceActions
|
5
|
+
def initialize(name, path, methods)
|
6
|
+
@name = name.to_s
|
7
|
+
@methods = methods
|
8
|
+
@path = path
|
9
|
+
end
|
10
|
+
|
11
|
+
protected
|
12
|
+
|
13
|
+
def show
|
14
|
+
get_action(name, :get, "#{path}/:id", 'show')
|
15
|
+
end
|
16
|
+
|
17
|
+
def edit
|
18
|
+
get_action(name, :get, "#{path}/:id/edit", 'edit')
|
19
|
+
end
|
20
|
+
|
21
|
+
def update
|
22
|
+
get_action(name, :put, "#{path}/:id", 'update')
|
23
|
+
end
|
24
|
+
|
25
|
+
def destroy
|
26
|
+
get_action(name, :delete, "#{path}/:id", 'destroy')
|
27
|
+
end
|
28
|
+
|
29
|
+
private
|
30
|
+
|
31
|
+
attr_reader :methods, :name, :path
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
metadata
ADDED
@@ -0,0 +1,187 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: kawaii-api
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.4
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- rybex
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2016-05-18 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bundler
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.7'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.7'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '10.0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '10.0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rspec
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: 3.4.0
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: 3.4.0
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: pry
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: 0.10.3
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: 0.10.3
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: rubocop
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - "~>"
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0.40'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - "~>"
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0.40'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: rack-test
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - "~>"
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: 0.6.3
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - "~>"
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: 0.6.3
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: rack
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - "~>"
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: 1.6.4
|
104
|
+
type: :runtime
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - "~>"
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: 1.6.4
|
111
|
+
- !ruby/object:Gem::Dependency
|
112
|
+
name: thor
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - "~>"
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: 0.19.1
|
118
|
+
type: :runtime
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
122
|
+
- - "~>"
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: 0.19.1
|
125
|
+
description: Micro API framework to develop web applications in ruby
|
126
|
+
email:
|
127
|
+
- tomek.rybka@gmail.com
|
128
|
+
executables:
|
129
|
+
- kawaii-api
|
130
|
+
extensions: []
|
131
|
+
extra_rdoc_files: []
|
132
|
+
files:
|
133
|
+
- LICENSE.txt
|
134
|
+
- README.md
|
135
|
+
- bin/kawaii-api
|
136
|
+
- kawaii.gemspec
|
137
|
+
- lib/kawaii.rb
|
138
|
+
- lib/kawaii/app.rb
|
139
|
+
- lib/kawaii/cli.rb
|
140
|
+
- lib/kawaii/controller.rb
|
141
|
+
- lib/kawaii/errors.rb
|
142
|
+
- lib/kawaii/generators/new_project.rb
|
143
|
+
- lib/kawaii/generators/templates/new_project/Gemfile.erb
|
144
|
+
- lib/kawaii/generators/templates/new_project/application.rb.erb
|
145
|
+
- lib/kawaii/generators/templates/new_project/config.ru.erb
|
146
|
+
- lib/kawaii/generators/templates/new_project/routes.rb.erb
|
147
|
+
- lib/kawaii/router.rb
|
148
|
+
- lib/kawaii/routing/action.rb
|
149
|
+
- lib/kawaii/routing/collection.rb
|
150
|
+
- lib/kawaii/routing/handler.rb
|
151
|
+
- lib/kawaii/routing/member.rb
|
152
|
+
- lib/kawaii/routing/namespace.rb
|
153
|
+
- lib/kawaii/routing/nested_path.rb
|
154
|
+
- lib/kawaii/routing/resource.rb
|
155
|
+
- lib/kawaii/routing/resources.rb
|
156
|
+
- lib/kawaii/routing/route.rb
|
157
|
+
- lib/kawaii/routing/routes.rb
|
158
|
+
- lib/kawaii/routing/services/extract_params_from_url.rb
|
159
|
+
- lib/kawaii/routing/services/find_controller.rb
|
160
|
+
- lib/kawaii/routing/services/generate_resource_actions.rb
|
161
|
+
- lib/kawaii/routing/services/generate_resources_actions.rb
|
162
|
+
- lib/kawaii/version.rb
|
163
|
+
homepage: https://github.com/rybex/kawaii
|
164
|
+
licenses:
|
165
|
+
- MIT
|
166
|
+
metadata: {}
|
167
|
+
post_install_message:
|
168
|
+
rdoc_options: []
|
169
|
+
require_paths:
|
170
|
+
- lib
|
171
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
172
|
+
requirements:
|
173
|
+
- - ">="
|
174
|
+
- !ruby/object:Gem::Version
|
175
|
+
version: '0'
|
176
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
177
|
+
requirements:
|
178
|
+
- - ">="
|
179
|
+
- !ruby/object:Gem::Version
|
180
|
+
version: '0'
|
181
|
+
requirements: []
|
182
|
+
rubyforge_project:
|
183
|
+
rubygems_version: 2.4.3
|
184
|
+
signing_key:
|
185
|
+
specification_version: 4
|
186
|
+
summary: Micro API framework
|
187
|
+
test_files: []
|