hanami-router 2.0.0.beta2 → 2.0.0.beta4

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 81061c98f91ba599e04ca8e16ac1ae9f8784e8398f3580b552cfa26885218b2e
4
- data.tar.gz: cd776fa30375c022808441897e3849ec76ef5a6d5b452b36a444851c10a4f99c
3
+ metadata.gz: 53dac1d070a5bbdfd29a6f6b53a508e0549211e114156d978fbe2850559fd529
4
+ data.tar.gz: 4c53a34b2208a43ffbdff6a940d98bf52bad7beb5c976ea635f38855c714ec73
5
5
  SHA512:
6
- metadata.gz: 3cdc82d97486a5d74893d8fdff7bd1f337dc5d64d6ff6407133519aef0b8a287b369231d973b62a4da5fdee7d07ecb766d3d0fd39a8e08aa3cd966a425fff238
7
- data.tar.gz: ccc62d079fba4374b74dde5b008e3de0d4d5eaf630c9608179bca0ad0ff7ba6b0584713bb320977950f7901d0404b601598b2d6c97ffa218be428e8be47b2380
6
+ metadata.gz: af90e79c8fe42aa2133616055388b9decc9d21fa9018c730fa4156fb5cdd056d386698eaf4a758e2719a8fa6d452be91a48b72f5fb66b340f09762ade7084467
7
+ data.tar.gz: cbc78fded67c18f1a18657e54d8f1de734bb90c06e20e72b97b282591dd22e9b4f00a3c71bfcf5ab99e817dd26d8e19aa6a0686b2d7e7104c892d9cb1a68295c
data/CHANGELOG.md CHANGED
@@ -2,6 +2,12 @@
2
2
 
3
3
  Rack compatible HTTP router for Ruby
4
4
 
5
+ ## v2.0.0.beta4 - 2022-10-24
6
+
7
+ ### Changed
8
+
9
+ - [Peter Solnica] `Hanami::Middleware::BodyParser` can be initialized with one or more formats and additional custom mime types per format (`Hanami::Middleware::BodyParser.new(app, [:json, :xml])` or `Hanami::Middleware::BodyParser.new(app, [json: "application/json+scim"])`) (#230)
10
+
5
11
  ## v2.0.0.beta2 - 2022-08-16
6
12
 
7
13
  ### Fixed
@@ -9,15 +9,38 @@ module Hanami
9
9
  # @api private
10
10
  # @since 1.3.0
11
11
  module ClassInterface
12
+ # Instantiate a new body parser instance and load its parsers
13
+ #
14
+ # @example
15
+ # Hanami::Middleware::BodyParser.new(->(env) { [200, {}, "app"] }, :json)
16
+ #
17
+ # Hanami::Middleware::BodyParser.new(
18
+ # ->(env) { [200, {}, "app"] }, [json: "application/json+scim"]
19
+ # )
20
+ #
21
+ # Hanami::Middleware::BodyParser.new(
22
+ # ->(env) { [200, {}, "app"] }, [json: ["application/json+scim", "application/ld+json"]]
23
+ # )
24
+ #
25
+ # @param app [#call]
26
+ # @param parser_specs [Symbol, Array<Hash>] parser name or name with mime-type(s)
27
+ #
28
+ # @api private
29
+ # @since 2.0.0
30
+ # @return BodyParser
31
+ def new(app, parser_specs)
32
+ super(app, build_parsers(parser_specs))
33
+ end
34
+
12
35
  # @api private
13
36
  # @since 1.3.0
14
- def for(parser)
37
+ def build(parser, **config)
15
38
  parser =
16
39
  case parser
17
40
  when String, Symbol
18
- require_parser(parser)
41
+ build(parser_class(parser), **config)
19
42
  when Class
20
- parser.new
43
+ parser.new(**config)
21
44
  else
22
45
  parser
23
46
  end
@@ -27,32 +50,76 @@ module Hanami
27
50
  parser
28
51
  end
29
52
 
53
+ # @api private
54
+ # @since 2.0.0
55
+ def build_parsers(parser_specs, registry = {})
56
+ return DEFAULT_BODY_PARSERS if parser_specs.empty?
57
+
58
+ parsers = Array(parser_specs).flatten(0)
59
+
60
+ parsers.each_with_object(registry) do |spec, memo|
61
+ if spec.is_a?(Hash) && spec.size > 1
62
+ spec.each do |key, value|
63
+ build_parsers([key => [value]], memo)
64
+ end
65
+ else
66
+ name, *mime_types = Array(*spec).flatten(0)
67
+
68
+ parser = build(name, mime_types: mime_types.flatten)
69
+
70
+ parser.mime_types.each do |mime|
71
+ memo[mime] = parser
72
+ end
73
+ end
74
+ end
75
+ end
76
+
30
77
  private
31
78
 
32
79
  # @api private
33
80
  # @since 1.3.0
34
81
  PARSER_METHODS = %i[mime_types parse].freeze
35
82
 
83
+ # @api private
84
+ # @since 2.0.0
85
+ DEFAULT_BODY_PARSERS = {}.freeze
86
+
36
87
  # @api private
37
88
  # @since 1.3.0
38
89
  def ensure_parser(parser)
39
- raise InvalidParserError.new(parser) unless PARSER_METHODS.all? { |method| parser.respond_to?(method) }
90
+ unless PARSER_METHODS.all? { |method| parser.respond_to?(method) }
91
+ raise InvalidParserError.new(parser)
92
+ end
40
93
  end
41
94
 
42
95
  # @api private
43
96
  # @since 1.3.0
44
- def require_parser(parser)
45
- require "hanami/middleware/body_parser/#{parser}_parser"
97
+ # rubocop:disable Lint/SuppressedException
98
+ def parser_class(parser_name)
99
+ parser = nil
100
+
101
+ begin
102
+ require "hanami/middleware/body_parser/#{parser_name}_parser"
103
+ rescue LoadError; end
104
+
105
+ begin
106
+ parser = load_parser!("#{classify(parser_name)}Parser")
107
+ rescue NameError; end
46
108
 
47
- load_parser!("#{classify(parser)}Parser").new
48
- rescue LoadError, NameError
49
- raise UnknownParserError.new(parser)
109
+ parser
110
+ ensure
111
+ raise UnknownParserError, parser_name unless parser
50
112
  end
113
+ # rubocop:enable Lint/SuppressedException
51
114
 
115
+ # @api private
116
+ # @since 1.3.0
52
117
  def classify(parser)
53
118
  parser.to_s.split(/_/).map(&:capitalize).join
54
119
  end
55
120
 
121
+ # @api private
122
+ # @since 1.3.0
56
123
  def load_parser!(class_name)
57
124
  Hanami::Middleware::BodyParser.const_get(class_name, false)
58
125
  end
@@ -11,7 +11,7 @@ module Hanami
11
11
  class JsonParser < Parser
12
12
  # @since 1.3.0
13
13
  # @api private
14
- def mime_types
14
+ def self.mime_types
15
15
  ["application/json", "application/vnd.api+json"]
16
16
  end
17
17
 
@@ -7,7 +7,9 @@ module Hanami
7
7
  #
8
8
  # @since 2.0.0
9
9
  class Parser
10
- # Declare supported MIME types
10
+ DEFAULT_MIME_TYPES = [].freeze
11
+
12
+ # Return supported mime types
11
13
  #
12
14
  # @return [Array<String>] supported MIME types
13
15
  #
@@ -18,12 +20,15 @@ module Hanami
18
20
  # require "hanami/middleware/body_parser"
19
21
  #
20
22
  # class XMLParser < Hanami::Middleware::BodyParser::Parser
21
- # def mime_types
23
+ # def self.mime_types
22
24
  # ["application/xml", "text/xml"]
23
25
  # end
24
26
  # end
25
- def mime_types
26
- raise NotImplementedError
27
+ attr_reader :mime_types
28
+
29
+ # @api private
30
+ def initialize(mime_types: DEFAULT_MIME_TYPES)
31
+ @mime_types = self.class.mime_types + mime_types
27
32
  end
28
33
 
29
34
  # Parse raw HTTP request body
@@ -37,7 +37,7 @@ module Hanami
37
37
 
38
38
  def initialize(app, parsers)
39
39
  @app = app
40
- @parsers = build_parsers(parsers)
40
+ @parsers = parsers
41
41
  end
42
42
 
43
43
  def call(env)
@@ -56,19 +56,6 @@ module Hanami
56
56
 
57
57
  private
58
58
 
59
- def build_parsers(parser_names)
60
- parser_names = Array(parser_names)
61
- return {} if parser_names.empty?
62
-
63
- parser_names.each_with_object({}) do |name, parsers|
64
- parser = self.class.for(name)
65
-
66
- parser.mime_types.each do |mime|
67
- parsers[mime] = parser
68
- end
69
- end
70
- end
71
-
72
59
  # @api private
73
60
  def _symbolize(body)
74
61
  if body.is_a?(::Hash)
@@ -4,6 +4,6 @@ module Hanami
4
4
  class Router
5
5
  # @since 0.1.0
6
6
  # @api public
7
- VERSION = "2.0.0.beta2"
7
+ VERSION = "2.0.0.beta4"
8
8
  end
9
9
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: hanami-router
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.0.beta2
4
+ version: 2.0.0.beta4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Luca Guidi
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-08-16 00:00:00.000000000 Z
11
+ date: 2022-10-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rack