shark-on-lambda 0.6.10 → 1.0.0.rc1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/workflows/push-gem.yml +67 -0
- data/.github/workflows/tests.yml +32 -0
- data/README.md +10 -12
- data/changelog.md +11 -0
- data/gems.locked +73 -23
- data/lib/shark_on_lambda/api_gateway_handler.rb +61 -0
- data/lib/shark_on_lambda/application.rb +17 -0
- data/lib/shark_on_lambda/base_controller.rb +50 -0
- data/lib/shark_on_lambda/configuration.rb +9 -1
- data/lib/shark_on_lambda/dispatcher.rb +26 -0
- data/lib/shark_on_lambda/errors/base.rb +47 -0
- data/lib/shark_on_lambda/errors/base_serializer.rb +18 -0
- data/lib/shark_on_lambda/jsonapi_controller.rb +29 -0
- data/lib/shark_on_lambda/jsonapi_parameters.rb +66 -0
- data/lib/shark_on_lambda/jsonapi_renderer.rb +115 -0
- data/lib/shark_on_lambda/middleware/base.rb +23 -0
- data/lib/shark_on_lambda/middleware/jsonapi_rescuer.rb +31 -0
- data/lib/shark_on_lambda/middleware/rescuer.rb +38 -0
- data/lib/shark_on_lambda/query.rb +67 -0
- data/lib/shark_on_lambda/rack_adapters/api_gateway.rb +127 -0
- data/lib/shark_on_lambda/request.rb +9 -0
- data/lib/shark_on_lambda/response.rb +6 -0
- data/lib/shark_on_lambda/rspec/env_builder.rb +64 -0
- data/lib/shark_on_lambda/rspec/helpers.rb +84 -0
- data/lib/shark_on_lambda/rspec/jsonapi_helpers.rb +27 -0
- data/lib/shark_on_lambda/version.rb +1 -1
- data/lib/shark_on_lambda.rb +25 -28
- data/shark-on-lambda.gemspec +8 -3
- metadata +104 -24
- data/.gitlab-ci.yml +0 -39
- data/.travis.yml +0 -14
- data/lib/shark_on_lambda/api_gateway/base_controller.rb +0 -76
- data/lib/shark_on_lambda/api_gateway/base_handler.rb +0 -82
- data/lib/shark_on_lambda/api_gateway/concerns/http_response_validation.rb +0 -61
- data/lib/shark_on_lambda/api_gateway/errors.rb +0 -49
- data/lib/shark_on_lambda/api_gateway/headers.rb +0 -37
- data/lib/shark_on_lambda/api_gateway/jsonapi_controller.rb +0 -77
- data/lib/shark_on_lambda/api_gateway/jsonapi_parameters.rb +0 -68
- data/lib/shark_on_lambda/api_gateway/jsonapi_renderer.rb +0 -105
- data/lib/shark_on_lambda/api_gateway/parameters.rb +0 -18
- data/lib/shark_on_lambda/api_gateway/query.rb +0 -69
- data/lib/shark_on_lambda/api_gateway/request.rb +0 -148
- data/lib/shark_on_lambda/api_gateway/response.rb +0 -82
- data/lib/shark_on_lambda/api_gateway/serializers/base_error_serializer.rb +0 -20
- data/lib/shark_on_lambda/concerns/filter_actions.rb +0 -93
- data/lib/shark_on_lambda/tasks/build.rake +0 -146
- data/lib/shark_on_lambda/tasks.rb +0 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9de95366ac135aebf072c6ecdbb5cae42b25f072bffdd1e01bee446e8262f17b
|
4
|
+
data.tar.gz: a09d5288e281447de50cfbbd8f97a18c023d9750e5d5b5ab456f4d6187b229a6
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz: '
|
6
|
+
metadata.gz: 9643f2cb448d20396f43ab9fd124e0aca1ae436773f1b29626ce44a644f12f6bd1477deb5c468a30b1992d824d1bf6049f8340705c11dde6a65432f1104bba38
|
7
|
+
data.tar.gz: '09d2eb6a2ffb09b969f3cd383a0f9a19ee6bd68fbf32b37ba1fc0acab488144dcf38d516788b421b601158d390e4eee162500c65efcb25e89f979ac4bb487c21'
|
@@ -0,0 +1,67 @@
|
|
1
|
+
name: Push Gem
|
2
|
+
on:
|
3
|
+
push:
|
4
|
+
tags:
|
5
|
+
- 'v*'
|
6
|
+
|
7
|
+
jobs:
|
8
|
+
rspec:
|
9
|
+
runs-on: ubuntu-latest
|
10
|
+
steps:
|
11
|
+
- uses: actions/checkout@v1
|
12
|
+
- name: Set up Ruby 2.5
|
13
|
+
uses: actions/setup-ruby@v1
|
14
|
+
with:
|
15
|
+
ruby-version: 2.5.x
|
16
|
+
- name: Run RSpec
|
17
|
+
run: |
|
18
|
+
gem install bundler
|
19
|
+
bundle install --jobs 4 --retry 3
|
20
|
+
bundle exec rspec
|
21
|
+
|
22
|
+
rubocop:
|
23
|
+
runs-on: ubuntu-latest
|
24
|
+
steps:
|
25
|
+
- uses: actions/checkout@v1
|
26
|
+
- name: Set up Ruby 2.5
|
27
|
+
uses: actions/setup-ruby@v1
|
28
|
+
with:
|
29
|
+
ruby-version: 2.5.x
|
30
|
+
- name: Run rubocop
|
31
|
+
run: |
|
32
|
+
gem install bundler
|
33
|
+
bundle install --jobs 4 --retry 3
|
34
|
+
bundle exec rubocop
|
35
|
+
|
36
|
+
push-gem:
|
37
|
+
runs-on: ubuntu-latest
|
38
|
+
steps:
|
39
|
+
- uses: actions/checkout@master
|
40
|
+
- name: Set up Ruby 2.5
|
41
|
+
uses: actions/setup-ruby@v1
|
42
|
+
with:
|
43
|
+
ruby-version: 2.5.x
|
44
|
+
- name: Build gem
|
45
|
+
run: |
|
46
|
+
gem install bundler
|
47
|
+
bundle install --jobs 4 --retry 3
|
48
|
+
bundle exec rake build
|
49
|
+
- name: Push to GitHub Package Repository
|
50
|
+
run: |
|
51
|
+
mkdir -p $HOME/.gem
|
52
|
+
echo ":github: Bearer $GEM_HOST_API_KEY" >> $HOME/.gem/credentials
|
53
|
+
chmod 0600 $HOME/.gem/credentials
|
54
|
+
bundle exec rake build
|
55
|
+
gem push --key github --host https://rubygems.pkg.github.com/Skudo pkg/`ls -1t pkg | head -1`
|
56
|
+
env:
|
57
|
+
GEM_HOST_API_KEY: ${{secrets.GITHUB_AUTH_TOKEN}}
|
58
|
+
OWNER: username
|
59
|
+
- name: Push to RubyGems
|
60
|
+
run: |
|
61
|
+
mkdir -p $HOME/.gem
|
62
|
+
echo ":rubygems_api_key: $GEM_HOST_API_KEY" >> ~/.gem/credentials
|
63
|
+
chmod 0600 $HOME/.gem/credentials
|
64
|
+
bundle exec rake build
|
65
|
+
gem push pkg/`ls -1t pkg | head -1`
|
66
|
+
env:
|
67
|
+
GEM_HOST_API_KEY: ${{secrets.RUBYGEMS_AUTH_TOKEN}}
|
@@ -0,0 +1,32 @@
|
|
1
|
+
name: Tests
|
2
|
+
|
3
|
+
on: [push]
|
4
|
+
|
5
|
+
jobs:
|
6
|
+
rspec:
|
7
|
+
runs-on: ubuntu-latest
|
8
|
+
steps:
|
9
|
+
- uses: actions/checkout@v1
|
10
|
+
- name: Set up Ruby 2.5
|
11
|
+
uses: actions/setup-ruby@v1
|
12
|
+
with:
|
13
|
+
ruby-version: 2.5.x
|
14
|
+
- name: Run RSpec
|
15
|
+
run: |
|
16
|
+
gem install bundler
|
17
|
+
bundle install --jobs 4 --retry 3
|
18
|
+
bundle exec rspec
|
19
|
+
|
20
|
+
rubocop:
|
21
|
+
runs-on: ubuntu-latest
|
22
|
+
steps:
|
23
|
+
- uses: actions/checkout@v1
|
24
|
+
- name: Set up Ruby 2.5
|
25
|
+
uses: actions/setup-ruby@v1
|
26
|
+
with:
|
27
|
+
ruby-version: 2.5.x
|
28
|
+
- name: Run rubocop
|
29
|
+
run: |
|
30
|
+
gem install bundler
|
31
|
+
bundle install --jobs 4 --retry 3
|
32
|
+
bundle exec rubocop
|
data/README.md
CHANGED
@@ -1,6 +1,5 @@
|
|
1
1
|
# shark-on-lambda
|
2
|
-
|
3
|
-
[![Travis CI Build Status](https://travis-ci.org/Skudo/shark-on-lambda.svg?branch=develop)](https://travis-ci.org/Skudo/shark-on-lambda)
|
2
|
+
[![GitHub Actions Test Status](https://github.com/Skudo/shark-on-lambda/workflows/Tests/badge.svg?branch=develop)](https://github.com/Skudo/shark-on-lambda/actions)
|
4
3
|
[![CodeClimate Maintainability Score](https://api.codeclimate.com/v1/badges/fb0c16b3c6212f97b753/maintainability)](https://codeclimate.com/github/Skudo/shark-on-lambda/maintainability)
|
5
4
|
|
6
5
|
`shark-on-lambda` provides a lightweight framework to write Ruby on AWS Lambda
|
@@ -24,8 +23,7 @@ maintaining a smaller memory footprint.
|
|
24
23
|
|
25
24
|
## Changelog
|
26
25
|
|
27
|
-
|
28
|
-
* Supports events from the API Gateway.
|
26
|
+
Have a look at the [actual changelog](changelog.md).
|
29
27
|
|
30
28
|
## Installation
|
31
29
|
|
@@ -50,11 +48,11 @@ are triggered by HTTP requests on the API Gateway. They also are responsible for
|
|
50
48
|
responding with a well-formed response to the caller.
|
51
49
|
|
52
50
|
```ruby
|
53
|
-
class MyHandler < SharkOnLambda::
|
51
|
+
class MyHandler < SharkOnLambda::BaseHandler
|
54
52
|
end
|
55
53
|
```
|
56
54
|
|
57
|
-
By inheriting from `SharkOnLambda::
|
55
|
+
By inheriting from `SharkOnLambda::BaseHandler`, your own handler
|
58
56
|
class is indirectly tied to your controller class by convention: It assumes
|
59
57
|
the controller name is `MyController` and it will dispatch events to that
|
60
58
|
controller.
|
@@ -63,7 +61,7 @@ If you however bring your own class with a different name, you can configure
|
|
63
61
|
your handler to use that controller instead:
|
64
62
|
|
65
63
|
```ruby
|
66
|
-
class MyHandler < SharkOnLambda::
|
64
|
+
class MyHandler < SharkOnLambda::BaseHandler
|
67
65
|
self.controller_class = AnotherController
|
68
66
|
end
|
69
67
|
```
|
@@ -72,7 +70,7 @@ All controller methods are going to be automagically mapped to class methods
|
|
72
70
|
on the handler class.
|
73
71
|
|
74
72
|
```ruby
|
75
|
-
class MyController < SharkOnLambda::
|
73
|
+
class MyController < SharkOnLambda::BaseController
|
76
74
|
def index
|
77
75
|
end
|
78
76
|
|
@@ -80,7 +78,7 @@ class MyController < SharkOnLambda::ApiGateway::BaseController
|
|
80
78
|
end
|
81
79
|
end
|
82
80
|
|
83
|
-
class MyHandler < SharkOnLambda::
|
81
|
+
class MyHandler < SharkOnLambda::BaseHandler
|
84
82
|
end
|
85
83
|
```
|
86
84
|
|
@@ -103,7 +101,7 @@ functions you may know from Rails and `render` does not really support multiple
|
|
103
101
|
renderers (yet).
|
104
102
|
|
105
103
|
```ruby
|
106
|
-
class MyController < SharkOnLambda::
|
104
|
+
class MyController < SharkOnLambda::BaseController
|
107
105
|
def index
|
108
106
|
# Make the API Gateway respond with a 201 response saying "Hello, World!"
|
109
107
|
# in the response body.
|
@@ -124,7 +122,7 @@ end
|
|
124
122
|
### _JSON API_-compliant controllers
|
125
123
|
|
126
124
|
If you inherit your controller from
|
127
|
-
`SharkOnLambda::
|
125
|
+
`SharkOnLambda::JsonapiController`, `render` and `redirect_to` will
|
128
126
|
create _JSON API_-compliant responses.
|
129
127
|
|
130
128
|
You however __must__ have a serialiser for the objects you want to render.
|
@@ -141,7 +139,7 @@ _JSON API_ compatibility. Therefore, we expect the serialisers to be inherited
|
|
141
139
|
from `::JSONAPI::Serializable::Resource` (or `::JSONAPI::Serializable::Error`).
|
142
140
|
|
143
141
|
```ruby
|
144
|
-
class SomethingSerializer <
|
142
|
+
class SomethingSerializer < JSONAPI::Serializable::Resource
|
145
143
|
type :somethings
|
146
144
|
|
147
145
|
attributes :foo, :bar, :baz
|
data/changelog.md
CHANGED
@@ -1,5 +1,16 @@
|
|
1
1
|
## Changelog
|
2
2
|
|
3
|
+
#### Unreleaesed
|
4
|
+
|
5
|
+
- [Break] HTTP redirection now uses the status code `302`.
|
6
|
+
- [Break] Remove the `ApiGateway` namespace, move all items from that namespace up by one level.
|
7
|
+
- [Break] Remove build rake tasks.
|
8
|
+
- Added support for Rack-compatible middleware.
|
9
|
+
- `SharkOnLambda::BaseController` now acts more like `ActionController::BaseController`.
|
10
|
+
- Support `ActiveModel::Errors` nested validation errors.
|
11
|
+
- Added `SharkOnLambda::RSpec::Helpers` and `SharkOnLambda::RSpec::JsonapiHelpers`.
|
12
|
+
- Moved to GitHub.
|
13
|
+
|
3
14
|
#### 0.6.10
|
4
15
|
|
5
16
|
- Upgrade `rack` for good measure.
|
data/gems.locked
CHANGED
@@ -1,14 +1,29 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
shark-on-lambda (0.
|
4
|
+
shark-on-lambda (1.0.0.rc1)
|
5
|
+
actionpack
|
5
6
|
activesupport
|
6
7
|
jsonapi-rb
|
7
|
-
rack (>= 2.0.8)
|
8
|
+
rack (>= 2.0.8, < 3)
|
9
|
+
zeitwerk (~> 2.2)
|
8
10
|
|
9
11
|
GEM
|
10
12
|
remote: https://rubygems.org/
|
11
13
|
specs:
|
14
|
+
actionpack (6.0.0)
|
15
|
+
actionview (= 6.0.0)
|
16
|
+
activesupport (= 6.0.0)
|
17
|
+
rack (~> 2.0)
|
18
|
+
rack-test (>= 0.6.3)
|
19
|
+
rails-dom-testing (~> 2.0)
|
20
|
+
rails-html-sanitizer (~> 1.0, >= 1.2.0)
|
21
|
+
actionview (6.0.0)
|
22
|
+
activesupport (= 6.0.0)
|
23
|
+
builder (~> 3.1)
|
24
|
+
erubi (~> 1.4)
|
25
|
+
rails-dom-testing (~> 2.0)
|
26
|
+
rails-html-sanitizer (~> 1.1, >= 1.2.0)
|
12
27
|
activemodel (6.0.0)
|
13
28
|
activesupport (= 6.0.0)
|
14
29
|
activesupport (6.0.0)
|
@@ -18,14 +33,23 @@ GEM
|
|
18
33
|
tzinfo (~> 1.1)
|
19
34
|
zeitwerk (~> 2.1, >= 2.1.8)
|
20
35
|
ast (2.4.0)
|
36
|
+
builder (3.2.4)
|
37
|
+
byebug (11.0.1)
|
38
|
+
coderay (1.1.2)
|
39
|
+
colorize (0.8.1)
|
21
40
|
concurrent-ruby (1.1.5)
|
41
|
+
crass (1.0.6)
|
22
42
|
diff-lcs (1.3)
|
23
43
|
docile (1.3.2)
|
24
|
-
|
44
|
+
erubi (1.9.0)
|
45
|
+
factory_bot (5.1.1)
|
25
46
|
activesupport (>= 4.2.0)
|
26
|
-
|
47
|
+
fasterer (0.8.2)
|
48
|
+
colorize (~> 0.7)
|
49
|
+
ruby_parser (>= 3.14.1)
|
50
|
+
i18n (1.7.0)
|
27
51
|
concurrent-ruby (~> 1.0)
|
28
|
-
jaro_winkler (1.5.
|
52
|
+
jaro_winkler (1.5.4)
|
29
53
|
json (2.2.0)
|
30
54
|
jsonapi-deserializable (0.2.0)
|
31
55
|
jsonapi-rb (0.5.0)
|
@@ -34,27 +58,47 @@ GEM
|
|
34
58
|
jsonapi-renderer (0.2.2)
|
35
59
|
jsonapi-serializable (0.3.1)
|
36
60
|
jsonapi-renderer (~> 0.2.0)
|
37
|
-
|
38
|
-
|
39
|
-
|
61
|
+
loofah (2.4.0)
|
62
|
+
crass (~> 1.0.2)
|
63
|
+
nokogiri (>= 1.5.9)
|
64
|
+
method_source (0.9.2)
|
65
|
+
mini_portile2 (2.4.0)
|
66
|
+
minitest (5.13.0)
|
67
|
+
nokogiri (1.10.8)
|
68
|
+
mini_portile2 (~> 2.4.0)
|
69
|
+
parallel (1.18.0)
|
70
|
+
parser (2.6.5.0)
|
40
71
|
ast (~> 2.4.0)
|
41
|
-
|
72
|
+
pry (0.12.2)
|
73
|
+
coderay (~> 1.1.0)
|
74
|
+
method_source (~> 0.9.0)
|
75
|
+
pry-byebug (3.7.0)
|
76
|
+
byebug (~> 11.0)
|
77
|
+
pry (~> 0.10)
|
78
|
+
rack (2.2.2)
|
79
|
+
rack-test (1.1.0)
|
80
|
+
rack (>= 1.0, < 3)
|
81
|
+
rails-dom-testing (2.0.3)
|
82
|
+
activesupport (>= 4.2.0)
|
83
|
+
nokogiri (>= 1.6)
|
84
|
+
rails-html-sanitizer (1.3.0)
|
85
|
+
loofah (~> 2.3)
|
42
86
|
rainbow (3.0.0)
|
43
87
|
rake (13.0.0)
|
44
|
-
rspec (3.
|
45
|
-
rspec-core (~> 3.
|
46
|
-
rspec-expectations (~> 3.
|
47
|
-
rspec-mocks (~> 3.
|
48
|
-
rspec-core (3.
|
49
|
-
rspec-support (~> 3.
|
50
|
-
rspec-expectations (3.
|
88
|
+
rspec (3.9.0)
|
89
|
+
rspec-core (~> 3.9.0)
|
90
|
+
rspec-expectations (~> 3.9.0)
|
91
|
+
rspec-mocks (~> 3.9.0)
|
92
|
+
rspec-core (3.9.0)
|
93
|
+
rspec-support (~> 3.9.0)
|
94
|
+
rspec-expectations (3.9.0)
|
51
95
|
diff-lcs (>= 1.2.0, < 2.0)
|
52
|
-
rspec-support (~> 3.
|
53
|
-
rspec-mocks (3.
|
96
|
+
rspec-support (~> 3.9.0)
|
97
|
+
rspec-mocks (3.9.0)
|
54
98
|
diff-lcs (>= 1.2.0, < 2.0)
|
55
|
-
rspec-support (~> 3.
|
56
|
-
rspec-support (3.
|
57
|
-
rubocop (0.
|
99
|
+
rspec-support (~> 3.9.0)
|
100
|
+
rspec-support (3.9.0)
|
101
|
+
rubocop (0.76.0)
|
58
102
|
jaro_winkler (~> 1.5.1)
|
59
103
|
parallel (~> 1.10)
|
60
104
|
parser (>= 2.6)
|
@@ -62,6 +106,9 @@ GEM
|
|
62
106
|
ruby-progressbar (~> 1.7)
|
63
107
|
unicode-display_width (>= 1.4.0, < 1.7)
|
64
108
|
ruby-progressbar (1.10.1)
|
109
|
+
ruby_parser (3.14.2)
|
110
|
+
sexp_processor (~> 4.9)
|
111
|
+
sexp_processor (4.14.1)
|
65
112
|
simplecov (0.17.1)
|
66
113
|
docile (~> 1.1)
|
67
114
|
json (>= 1.8, < 3)
|
@@ -72,7 +119,7 @@ GEM
|
|
72
119
|
thread_safe (~> 0.1)
|
73
120
|
unicode-display_width (1.6.0)
|
74
121
|
yard (0.9.20)
|
75
|
-
zeitwerk (2.1
|
122
|
+
zeitwerk (2.2.1)
|
76
123
|
|
77
124
|
PLATFORMS
|
78
125
|
ruby
|
@@ -81,6 +128,9 @@ DEPENDENCIES
|
|
81
128
|
activemodel
|
82
129
|
bundler
|
83
130
|
factory_bot
|
131
|
+
fasterer
|
132
|
+
pry
|
133
|
+
pry-byebug
|
84
134
|
rake
|
85
135
|
rspec
|
86
136
|
rubocop
|
@@ -89,4 +139,4 @@ DEPENDENCIES
|
|
89
139
|
yard
|
90
140
|
|
91
141
|
BUNDLED WITH
|
92
|
-
2.1.
|
142
|
+
2.1.4
|
@@ -0,0 +1,61 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module SharkOnLambda
|
4
|
+
class ApiGatewayHandler
|
5
|
+
class << self
|
6
|
+
attr_writer :controller_class_name
|
7
|
+
|
8
|
+
def controller_action?(action)
|
9
|
+
controller_actions.include?(action.to_sym)
|
10
|
+
end
|
11
|
+
|
12
|
+
def controller_class_name
|
13
|
+
return @controller_class_name if defined?(@controller_class_name)
|
14
|
+
|
15
|
+
name_inferrer = Inferrers::NameInferrer.from_handler_name(name)
|
16
|
+
@controller_class_name = name_inferrer.controller
|
17
|
+
end
|
18
|
+
|
19
|
+
private
|
20
|
+
|
21
|
+
def controller_actions
|
22
|
+
return [] if controller_class.nil?
|
23
|
+
|
24
|
+
controller_class.public_instance_methods(false)
|
25
|
+
end
|
26
|
+
|
27
|
+
def controller_class
|
28
|
+
controller_class_name.safe_constantize
|
29
|
+
end
|
30
|
+
|
31
|
+
def method_missing(action, *args, &_block)
|
32
|
+
return super unless respond_to_missing?(action)
|
33
|
+
|
34
|
+
new.call(action, *args)
|
35
|
+
end
|
36
|
+
|
37
|
+
def respond_to_missing?(name, _include_all = false)
|
38
|
+
controller_action?(name)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
attr_reader :application, :env
|
43
|
+
delegate :context, :event, to: :adapter
|
44
|
+
|
45
|
+
def initialize
|
46
|
+
@application = Application.new
|
47
|
+
end
|
48
|
+
|
49
|
+
def call(action, event:, context:)
|
50
|
+
raise NoMethodError unless self.class.controller_action?(action)
|
51
|
+
|
52
|
+
adapter = RackAdapters::ApiGateway.new(context: context, event: event)
|
53
|
+
env = adapter.env
|
54
|
+
env['shark.controller'] = self.class.controller_class_name
|
55
|
+
env['shark.action'] = action.to_s
|
56
|
+
|
57
|
+
status, headers, body = @application.call(env)
|
58
|
+
adapter.build_response(status, headers, body)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module SharkOnLambda
|
4
|
+
class Application
|
5
|
+
def call(env)
|
6
|
+
dup.send('_call', env)
|
7
|
+
end
|
8
|
+
|
9
|
+
private
|
10
|
+
|
11
|
+
def _call(env)
|
12
|
+
dispatcher = SharkOnLambda.config.dispatcher
|
13
|
+
middleware_stack = SharkOnLambda.config.middleware.build(dispatcher)
|
14
|
+
middleware_stack.call(env)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module SharkOnLambda
|
4
|
+
class BaseController < ActionController::Metal
|
5
|
+
EXCLUDED_MODULES = [
|
6
|
+
AbstractController::Translation,
|
7
|
+
AbstractController::AssetPaths,
|
8
|
+
|
9
|
+
ActionController::UrlFor,
|
10
|
+
ActionController::ConditionalGet,
|
11
|
+
ActionController::EtagWithTemplateDigest,
|
12
|
+
ActionController::EtagWithFlash,
|
13
|
+
ActionController::Caching,
|
14
|
+
ActionController::MimeResponds,
|
15
|
+
ActionController::ImplicitRender,
|
16
|
+
ActionController::Cookies,
|
17
|
+
ActionController::Flash,
|
18
|
+
ActionController::FormBuilder,
|
19
|
+
ActionController::RequestForgeryProtection,
|
20
|
+
ActionController::ContentSecurityPolicy,
|
21
|
+
ActionController::ForceSSL,
|
22
|
+
ActionController::HttpAuthentication::Basic::ControllerMethods,
|
23
|
+
ActionController::HttpAuthentication::Digest::ControllerMethods,
|
24
|
+
ActionController::HttpAuthentication::Token::ControllerMethods,
|
25
|
+
ActionView::Layouts
|
26
|
+
].freeze
|
27
|
+
ActionController::Base.without_modules(EXCLUDED_MODULES).each do |mod|
|
28
|
+
include mod
|
29
|
+
end
|
30
|
+
|
31
|
+
def self.dispatch(*)
|
32
|
+
super
|
33
|
+
rescue AbstractController::ActionNotFound,
|
34
|
+
AbstractController::DoubleRenderError,
|
35
|
+
ActionController::ActionControllerError => e
|
36
|
+
raise Errors[500], e.message
|
37
|
+
end
|
38
|
+
|
39
|
+
def redirect_to(*)
|
40
|
+
super
|
41
|
+
self.response_body = '' if no_body?
|
42
|
+
end
|
43
|
+
|
44
|
+
private
|
45
|
+
|
46
|
+
def no_body?
|
47
|
+
response.status.in?(Response::NO_CONTENT_CODES)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
@@ -4,7 +4,7 @@ module SharkOnLambda
|
|
4
4
|
class Configuration < OpenStruct
|
5
5
|
include Concerns::ResettableSingleton
|
6
6
|
|
7
|
-
attr_writer :stage
|
7
|
+
attr_writer :dispatcher, :stage
|
8
8
|
|
9
9
|
class << self
|
10
10
|
include Concerns::YamlConfigLoader
|
@@ -56,6 +56,14 @@ module SharkOnLambda
|
|
56
56
|
end
|
57
57
|
end
|
58
58
|
|
59
|
+
def dispatcher
|
60
|
+
@dispatcher ||= Dispatcher.new
|
61
|
+
end
|
62
|
+
|
63
|
+
def middleware
|
64
|
+
@middleware ||= ActionDispatch::MiddlewareStack.new
|
65
|
+
end
|
66
|
+
|
59
67
|
def root
|
60
68
|
@root ||= Pathname.new('.')
|
61
69
|
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module SharkOnLambda
|
4
|
+
class Dispatcher
|
5
|
+
def call(env)
|
6
|
+
request = Request.new(env)
|
7
|
+
response = Response.new
|
8
|
+
|
9
|
+
controller = controller_class(env)
|
10
|
+
action = controller_action(env)
|
11
|
+
controller.dispatch(action, request, response)
|
12
|
+
|
13
|
+
response.prepare!
|
14
|
+
end
|
15
|
+
|
16
|
+
private
|
17
|
+
|
18
|
+
def controller_action(env)
|
19
|
+
env['shark.action']
|
20
|
+
end
|
21
|
+
|
22
|
+
def controller_class(env)
|
23
|
+
env['shark.controller'].camelize.constantize
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module SharkOnLambda
|
4
|
+
module Errors
|
5
|
+
class Base < StandardError
|
6
|
+
attr_accessor :id, :code, :meta, :pointer, :parameter
|
7
|
+
attr_writer :detail
|
8
|
+
|
9
|
+
def self.status(status_code)
|
10
|
+
define_method :status do
|
11
|
+
status_code
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def detail
|
16
|
+
return @detail if @detail.present?
|
17
|
+
return nil if message == self.class.name
|
18
|
+
|
19
|
+
message
|
20
|
+
end
|
21
|
+
|
22
|
+
def title
|
23
|
+
Rack::Utils::HTTP_STATUS_CODES[status]
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def self.[](status_code)
|
28
|
+
@errors[status_code]
|
29
|
+
end
|
30
|
+
|
31
|
+
@errors = Rack::Utils::HTTP_STATUS_CODES.map do |status_code, message|
|
32
|
+
next unless (400..599).cover?(status_code) && message.present?
|
33
|
+
|
34
|
+
error_class = Class.new(Base) do
|
35
|
+
status status_code
|
36
|
+
end
|
37
|
+
class_name_parts = message.to_s.split(/\s+/)
|
38
|
+
class_name_parts.map! { |word| word.gsub(/[^a-z]/i, '').capitalize }
|
39
|
+
class_name = class_name_parts.join('')
|
40
|
+
const_set(class_name, error_class)
|
41
|
+
|
42
|
+
[status_code, error_class]
|
43
|
+
end
|
44
|
+
@errors.compact!
|
45
|
+
@errors = @errors.to_h
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module SharkOnLambda
|
4
|
+
module Errors
|
5
|
+
class BaseSerializer < JSONAPI::Serializable::Error
|
6
|
+
id { @object.id }
|
7
|
+
status { @object.status }
|
8
|
+
code { @object.code }
|
9
|
+
title { @object.title }
|
10
|
+
detail { @object.detail }
|
11
|
+
meta { @object.meta }
|
12
|
+
source do
|
13
|
+
pointer @object.pointer if @object.pointer.present?
|
14
|
+
parameter @object.parameter if @object.parameter.present?
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module SharkOnLambda
|
4
|
+
class JsonapiController < BaseController
|
5
|
+
ActionController::Renderers.add :jsonapi do |object, options|
|
6
|
+
response.set_header('content-type', 'application/vnd.api+json')
|
7
|
+
return { data: {} }.to_json if object.nil?
|
8
|
+
|
9
|
+
jsonapi_params = JsonapiParameters.new(params)
|
10
|
+
jsonapi_renderer = JsonapiRenderer.new
|
11
|
+
render_options = jsonapi_params.to_h.deep_merge(options)
|
12
|
+
|
13
|
+
jsonapi_renderer.render(object, render_options)
|
14
|
+
end
|
15
|
+
|
16
|
+
def redirect_to(options = {}, response_status = {})
|
17
|
+
super
|
18
|
+
return if response_status[:status] == 304
|
19
|
+
|
20
|
+
self.response_body = { data: {} }.to_json
|
21
|
+
end
|
22
|
+
|
23
|
+
def render(object, options = {})
|
24
|
+
options.merge!(jsonapi: object, content_type: 'application/vnd.api+json')
|
25
|
+
|
26
|
+
super(options)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|