hanami-router 2.0.0.beta2 → 2.0.0.beta4

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 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