shark-on-lambda 1.0.1 → 2.0.0.rc1
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/.rubocop.yml +4 -0
- data/changelog.md +10 -0
- data/doc/upgrade-from-0.6.x-to-1.x.md +3 -3
- data/lib/shark-on-lambda.rb +9 -0
- data/lib/shark_on_lambda.rb +10 -58
- data/lib/shark_on_lambda/api_gateway_handler.rb +3 -55
- data/lib/shark_on_lambda/application.rb +72 -2
- data/lib/shark_on_lambda/base_controller.rb +29 -9
- data/lib/shark_on_lambda/configuration.rb +1 -65
- data/lib/shark_on_lambda/inferrers/serializer_inferrer.rb +10 -7
- data/lib/shark_on_lambda/jsonapi_renderer.rb +1 -2
- data/lib/shark_on_lambda/middleware/honeybadger.rb +5 -3
- data/lib/shark_on_lambda/middleware/jsonapi_rescuer.rb +21 -1
- data/lib/shark_on_lambda/middleware/lambda_logger.rb +5 -13
- data/lib/shark_on_lambda/rake_tasks.rb +16 -0
- data/lib/shark_on_lambda/request.rb +0 -3
- data/lib/shark_on_lambda/rspec/env_builder.rb +71 -37
- data/lib/shark_on_lambda/rspec/helpers.rb +5 -88
- data/lib/shark_on_lambda/rspec/request_helpers.rb +63 -0
- data/lib/shark_on_lambda/rspec/{jsonapi_helpers.rb → response_helpers.rb} +4 -10
- data/lib/shark_on_lambda/version.rb +1 -1
- data/shark-on-lambda.gemspec +7 -5
- metadata +32 -39
- data/lib/shark_on_lambda/concerns/resettable_singleton.rb +0 -18
- data/lib/shark_on_lambda/concerns/yaml_config_loader.rb +0 -28
- data/lib/shark_on_lambda/dispatcher.rb +0 -26
- data/lib/shark_on_lambda/inferrers/name_inferrer.rb +0 -66
- data/lib/shark_on_lambda/jsonapi_controller.rb +0 -32
- data/lib/shark_on_lambda/middleware/rescuer.rb +0 -37
- data/lib/shark_on_lambda/query.rb +0 -67
- data/lib/shark_on_lambda/rack_adapters/api_gateway.rb +0 -128
- data/lib/shark_on_lambda/secrets.rb +0 -43
@@ -1,67 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module SharkOnLambda
|
4
|
-
# The `multiValueQueryStringParameters` object from the API Gateway event
|
5
|
-
# keeps _all_ values in an array, regardless of the actual size of the array
|
6
|
-
# and regardless of the "intent" of the query string parameter.
|
7
|
-
#
|
8
|
-
# In order to normalise this behaviour, we treat the query strings
|
9
|
-
#
|
10
|
-
# `key=value1&key=value2`
|
11
|
-
#
|
12
|
-
# and
|
13
|
-
#
|
14
|
-
# `key[]=value1&key[]=value2`
|
15
|
-
#
|
16
|
-
# the same. Both are to be serialised to the query string
|
17
|
-
#
|
18
|
-
# `key[]=value1&key[]=value2`
|
19
|
-
#
|
20
|
-
# However, the query strings
|
21
|
-
#
|
22
|
-
# `key=value`
|
23
|
-
#
|
24
|
-
# and
|
25
|
-
#
|
26
|
-
# `key[]=value`
|
27
|
-
#
|
28
|
-
# are _not_ to be treated the same.
|
29
|
-
class Query
|
30
|
-
def initialize(data = {})
|
31
|
-
@params = HashWithIndifferentAccess.new.merge(data)
|
32
|
-
end
|
33
|
-
|
34
|
-
def add(key, values)
|
35
|
-
if key.to_s.end_with?('[]')
|
36
|
-
actual_key = key[0..-3]
|
37
|
-
add_list(actual_key, values)
|
38
|
-
else
|
39
|
-
values.each { |value| add_item(key, value) }
|
40
|
-
end
|
41
|
-
end
|
42
|
-
|
43
|
-
def to_h
|
44
|
-
@params
|
45
|
-
end
|
46
|
-
|
47
|
-
def to_s
|
48
|
-
Rack::Utils.build_nested_query(to_h)
|
49
|
-
end
|
50
|
-
|
51
|
-
private
|
52
|
-
|
53
|
-
def add_item(key, value)
|
54
|
-
if @params[key].nil?
|
55
|
-
@params[key] = value
|
56
|
-
else
|
57
|
-
@params[key] = Array(@params[key])
|
58
|
-
@params[key] << value
|
59
|
-
end
|
60
|
-
end
|
61
|
-
|
62
|
-
def add_list(key, value)
|
63
|
-
@params[key] ||= []
|
64
|
-
@params[key].concat(value)
|
65
|
-
end
|
66
|
-
end
|
67
|
-
end
|
@@ -1,128 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module SharkOnLambda
|
4
|
-
module RackAdapters
|
5
|
-
class ApiGateway
|
6
|
-
attr_reader :context, :event
|
7
|
-
|
8
|
-
def initialize(context:, event:)
|
9
|
-
@context = context
|
10
|
-
@event = event.deep_stringify_keys
|
11
|
-
end
|
12
|
-
|
13
|
-
def build_response(status, headers, body)
|
14
|
-
body_content = ''
|
15
|
-
body.each { |line| body_content += line.to_s }
|
16
|
-
response = {
|
17
|
-
'statusCode' => status,
|
18
|
-
'headers' => headers,
|
19
|
-
'body' => body_content
|
20
|
-
}
|
21
|
-
response['isBase64Encoded'] = false if elb?
|
22
|
-
response.with_indifferent_access
|
23
|
-
end
|
24
|
-
|
25
|
-
def env
|
26
|
-
default_env.merge(env_request_metadata)
|
27
|
-
.merge(env_headers)
|
28
|
-
.merge(env_params)
|
29
|
-
.merge(env_body)
|
30
|
-
end
|
31
|
-
|
32
|
-
private
|
33
|
-
|
34
|
-
def default_env
|
35
|
-
{
|
36
|
-
'SCRIPT_NAME' => '',
|
37
|
-
'rack.version' => Rack::VERSION,
|
38
|
-
'rack.errors' => $stderr,
|
39
|
-
'rack.multithread' => true,
|
40
|
-
'rack.multiprocess' => true,
|
41
|
-
'rack.run_once' => false
|
42
|
-
}
|
43
|
-
end
|
44
|
-
|
45
|
-
def elb?
|
46
|
-
return false if event['requestContext'].nil?
|
47
|
-
|
48
|
-
event['requestContext'].key?('elb')
|
49
|
-
end
|
50
|
-
|
51
|
-
def env_body
|
52
|
-
result = event['body'] || ''
|
53
|
-
result = Base64.decode64(result) if event['isBase64Encoded']
|
54
|
-
|
55
|
-
{
|
56
|
-
'rack.input' => StringIO.new(result).set_encoding(Encoding::BINARY),
|
57
|
-
'CONTENT_LENGTH' => result.bytesize.to_s
|
58
|
-
}
|
59
|
-
end
|
60
|
-
|
61
|
-
def env_headers
|
62
|
-
result = {}
|
63
|
-
http_headers.each_pair do |header, value|
|
64
|
-
key = key_for_header(header)
|
65
|
-
result[key] = value.to_s
|
66
|
-
end
|
67
|
-
result
|
68
|
-
end
|
69
|
-
|
70
|
-
def env_params
|
71
|
-
{
|
72
|
-
'QUERY_STRING' => query_string,
|
73
|
-
'shark.path_parameters' => event['pathParameters']
|
74
|
-
}
|
75
|
-
end
|
76
|
-
|
77
|
-
def env_request_metadata
|
78
|
-
{
|
79
|
-
'REQUEST_METHOD' => event['httpMethod'],
|
80
|
-
'PATH_INFO' => path_info,
|
81
|
-
'SERVER_NAME' => server_name,
|
82
|
-
'SERVER_PORT' => server_port.to_s,
|
83
|
-
'rack.url_scheme' => url_scheme
|
84
|
-
}
|
85
|
-
end
|
86
|
-
|
87
|
-
def http_headers
|
88
|
-
event['headers'] || {}
|
89
|
-
end
|
90
|
-
|
91
|
-
def key_for_header(header)
|
92
|
-
key = header.upcase.tr('-', '_')
|
93
|
-
case key
|
94
|
-
when 'CONTENT_LENGTH', 'CONTENT_TYPE' then key
|
95
|
-
else "HTTP_#{key}"
|
96
|
-
end
|
97
|
-
end
|
98
|
-
|
99
|
-
def path_info
|
100
|
-
event['path'] || ''
|
101
|
-
end
|
102
|
-
|
103
|
-
def query_string
|
104
|
-
return @query_string if defined?(@query_string)
|
105
|
-
|
106
|
-
query = Query.new
|
107
|
-
event['multiValueQueryStringParameters']&.each_pair do |key, value|
|
108
|
-
query.add(key, value)
|
109
|
-
end
|
110
|
-
@query_string = query.to_s
|
111
|
-
end
|
112
|
-
|
113
|
-
def server_name
|
114
|
-
http_headers['Host'] || 'localhost'
|
115
|
-
end
|
116
|
-
|
117
|
-
def server_port
|
118
|
-
http_headers['X-Forwarded-Port'] || 443
|
119
|
-
end
|
120
|
-
|
121
|
-
def url_scheme
|
122
|
-
http_headers['CloudFront-Forwarded-Proto'] ||
|
123
|
-
http_headers['X-Forwarded-Proto'] ||
|
124
|
-
'https'
|
125
|
-
end
|
126
|
-
end
|
127
|
-
end
|
128
|
-
end
|
@@ -1,43 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module SharkOnLambda
|
4
|
-
class Secrets < OpenStruct
|
5
|
-
include Concerns::ResettableSingleton
|
6
|
-
|
7
|
-
class << self
|
8
|
-
include Concerns::YamlConfigLoader
|
9
|
-
|
10
|
-
attr_writer :files
|
11
|
-
|
12
|
-
def load(stage, fallback: :default)
|
13
|
-
load_secrets(stage, fallback: fallback)
|
14
|
-
|
15
|
-
instance
|
16
|
-
end
|
17
|
-
|
18
|
-
def files
|
19
|
-
return @files if defined?(@files)
|
20
|
-
|
21
|
-
@files = paths(%w[config/secrets.yml config/secrets.local.yml])
|
22
|
-
end
|
23
|
-
|
24
|
-
protected
|
25
|
-
|
26
|
-
def load_secrets(stage, fallback:)
|
27
|
-
secrets = load_yaml_files(stage: stage,
|
28
|
-
fallback: fallback,
|
29
|
-
paths: files)
|
30
|
-
secrets.each_pair { |key, value| instance.send("#{key}=", value) }
|
31
|
-
end
|
32
|
-
|
33
|
-
def paths(files)
|
34
|
-
files.map { |file| SharkOnLambda.config.root.join(file) }
|
35
|
-
end
|
36
|
-
end
|
37
|
-
|
38
|
-
def inspect
|
39
|
-
# Do not display all the internals of this object when #inspect is called.
|
40
|
-
"#<#{self.class.name}>"
|
41
|
-
end
|
42
|
-
end
|
43
|
-
end
|