itsi-server 0.2.2 → 0.2.3

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: 945215c55c27ed88c72156d88ab5606ec321dbb609406a2fa301d620a2dfdb8d
4
- data.tar.gz: 74682a5850c9c2d1a2c449550bbeedd932e153dc8e753e5224fcc98999d51353
3
+ metadata.gz: 28ba76ce129635022bb442e61f18dac9c6d29d7552b7b2e006ec16b8c5ef975a
4
+ data.tar.gz: 944d5bfee24014c8aab5bffede13f73d6316023dcda9df7cbaf7e6fb442f8d9d
5
5
  SHA512:
6
- metadata.gz: 2239fac3020f7b9887765b41ab42ea9ffabe08b338875608857b96e93f307637bcf872f5d855feb8906a5cbffd057ea2b0d6a3e9148d3ce9d706b531cd41a897
7
- data.tar.gz: 23aab8255a3d5e7bb731c32f65ce340a632363b482dba3f1674c99b4bbb5d22728197523d515205ef18a91b19ea8307fc27144b14d22d186ead5de746d6deb21
6
+ metadata.gz: 658829fb38833abdd60bbb175f552faddfa26692598626a25a546845bcbe4f1b6478f268b2917c6ef08b5ebf86e93c3bace063ba0594e2a774dca3810d616ce4
7
+ data.tar.gz: 9089b2a6067e148a8893f8e12e07e9e7fa1e3625b6a8940d3bf4fbae3aa81d3b10ab538250c8a15bdca084d0a603480554bb1663b73deccfc68c6deaba560205
data/Cargo.lock CHANGED
@@ -117,9 +117,9 @@ dependencies = [
117
117
 
118
118
  [[package]]
119
119
  name = "anyhow"
120
- version = "1.0.97"
120
+ version = "1.0.98"
121
121
  source = "registry+https://github.com/rust-lang/crates.io-index"
122
- checksum = "dcfed56ad506cb2c684a14971b8861fdc3baaaae314b9e5f9bb532cbe3ba7a4f"
122
+ checksum = "e16d2d3311acee920a9eb8d33b8cbc1787ce4a264e85f964c2404b969bdcd487"
123
123
 
124
124
  [[package]]
125
125
  name = "arc-swap"
@@ -253,9 +253,9 @@ dependencies = [
253
253
 
254
254
  [[package]]
255
255
  name = "aws-lc-sys"
256
- version = "0.28.0"
256
+ version = "0.28.2"
257
257
  source = "registry+https://github.com/rust-lang/crates.io-index"
258
- checksum = "b9f7720b74ed28ca77f90769a71fd8c637a0137f6fae4ae947e1050229cff57f"
258
+ checksum = "bfa9b6986f250236c27e5a204062434a773a13243d2ffc2955f37bdba4c5c6a1"
259
259
  dependencies = [
260
260
  "bindgen",
261
261
  "cc",
@@ -467,9 +467,9 @@ dependencies = [
467
467
 
468
468
  [[package]]
469
469
  name = "brotli-decompressor"
470
- version = "4.0.2"
470
+ version = "4.0.3"
471
471
  source = "registry+https://github.com/rust-lang/crates.io-index"
472
- checksum = "74fa05ad7d803d413eb8380983b092cbbaf9a85f151b871360e7b00cd7060b37"
472
+ checksum = "a334ef7c9e23abf0ce748e8cd309037da93e606ad52eb372e4ce327a0dcfbdfd"
473
473
  dependencies = [
474
474
  "alloc-no-stdlib",
475
475
  "alloc-stdlib",
@@ -587,9 +587,9 @@ dependencies = [
587
587
 
588
588
  [[package]]
589
589
  name = "clap"
590
- version = "4.5.36"
590
+ version = "4.5.37"
591
591
  source = "registry+https://github.com/rust-lang/crates.io-index"
592
- checksum = "2df961d8c8a0d08aa9945718ccf584145eee3f3aa06cddbeac12933781102e04"
592
+ checksum = "eccb054f56cbd38340b380d4a8e69ef1f02f1af43db2f0cc817a4774d80ae071"
593
593
  dependencies = [
594
594
  "clap_builder",
595
595
  "clap_derive",
@@ -597,9 +597,9 @@ dependencies = [
597
597
 
598
598
  [[package]]
599
599
  name = "clap_builder"
600
- version = "4.5.36"
600
+ version = "4.5.37"
601
601
  source = "registry+https://github.com/rust-lang/crates.io-index"
602
- checksum = "132dbda40fb6753878316a489d5a1242a8ef2f0d9e47ba01c951ea8aa7d013a5"
602
+ checksum = "efd9466fac8543255d3b1fcad4762c5e116ffe808c8a3043d4263cd4fd4862a2"
603
603
  dependencies = [
604
604
  "anstream",
605
605
  "anstyle",
@@ -764,9 +764,9 @@ dependencies = [
764
764
 
765
765
  [[package]]
766
766
  name = "data-encoding"
767
- version = "2.8.0"
767
+ version = "2.9.0"
768
768
  source = "registry+https://github.com/rust-lang/crates.io-index"
769
- checksum = "575f75dfd25738df5b91b8e43e14d44bda14637a58fae779fd2b064f8bf3e010"
769
+ checksum = "2a2330da5de22e8a3cb63252ce2abb30116bf5265e89c0e01bc17015ce30a476"
770
770
 
771
771
  [[package]]
772
772
  name = "der-parser"
@@ -1176,9 +1176,9 @@ dependencies = [
1176
1176
 
1177
1177
  [[package]]
1178
1178
  name = "h2"
1179
- version = "0.4.8"
1179
+ version = "0.4.9"
1180
1180
  source = "registry+https://github.com/rust-lang/crates.io-index"
1181
- checksum = "5017294ff4bb30944501348f6f8e42e6ad28f42c8bbef7a74029aff064a4e3c2"
1181
+ checksum = "75249d144030531f8dee69fe9cea04d3edf809a017ae445e2abdff6629e86633"
1182
1182
  dependencies = [
1183
1183
  "atomic-waker",
1184
1184
  "bytes",
@@ -1363,7 +1363,7 @@ dependencies = [
1363
1363
  "bytes",
1364
1364
  "futures-channel",
1365
1365
  "futures-util",
1366
- "h2 0.4.8",
1366
+ "h2 0.4.9",
1367
1367
  "http 1.3.1",
1368
1368
  "http-body 1.0.1",
1369
1369
  "httparse",
@@ -1644,7 +1644,7 @@ checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c"
1644
1644
 
1645
1645
  [[package]]
1646
1646
  name = "itsi-server"
1647
- version = "0.2.2"
1647
+ version = "0.2.3"
1648
1648
  dependencies = [
1649
1649
  "argon2",
1650
1650
  "async-channel",
@@ -1681,7 +1681,7 @@ dependencies = [
1681
1681
  "parking_lot",
1682
1682
  "percent-encoding",
1683
1683
  "pin-project",
1684
- "rand 0.9.0",
1684
+ "rand 0.9.1",
1685
1685
  "rcgen",
1686
1686
  "redis",
1687
1687
  "regex",
@@ -1713,7 +1713,7 @@ dependencies = [
1713
1713
  "axum-server",
1714
1714
  "base64 0.22.1",
1715
1715
  "chrono",
1716
- "clap 4.5.36",
1716
+ "clap 4.5.37",
1717
1717
  "futures",
1718
1718
  "log",
1719
1719
  "num-bigint",
@@ -1841,9 +1841,9 @@ checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55"
1841
1841
 
1842
1842
  [[package]]
1843
1843
  name = "libc"
1844
- version = "0.2.171"
1844
+ version = "0.2.172"
1845
1845
  source = "registry+https://github.com/rust-lang/crates.io-index"
1846
- checksum = "c19937216e9d3aa9956d9bb8dfc0b0c8beb6058fc4f7a4dc4d850edf86a237d6"
1846
+ checksum = "d750af042f7ef4f724306de029d18836c26c1765a54a6a3f094cbd23a7267ffa"
1847
1847
 
1848
1848
  [[package]]
1849
1849
  name = "libloading"
@@ -1852,7 +1852,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
1852
1852
  checksum = "fc2f4eb4bc735547cfed7c0a4922cbd04a4655978c09b54f1f7b228750664c34"
1853
1853
  dependencies = [
1854
1854
  "cfg-if",
1855
- "windows-targets 0.52.6",
1855
+ "windows-targets 0.48.5",
1856
1856
  ]
1857
1857
 
1858
1858
  [[package]]
@@ -2366,9 +2366,9 @@ dependencies = [
2366
2366
 
2367
2367
  [[package]]
2368
2368
  name = "proc-macro2"
2369
- version = "1.0.94"
2369
+ version = "1.0.95"
2370
2370
  source = "registry+https://github.com/rust-lang/crates.io-index"
2371
- checksum = "a31971752e70b8b2686d7e46ec17fb38dad4051d94024c88df49b667caea9c84"
2371
+ checksum = "02b3e5e68a3a1a02aad3ec490a98007cbc13c37cbe84a3cd7b8e406d76e7f778"
2372
2372
  dependencies = [
2373
2373
  "unicode-ident",
2374
2374
  ]
@@ -2401,7 +2401,7 @@ checksum = "b820744eb4dc9b57a3398183639c511b5a26d2ed702cedd3febaa1393caa22cc"
2401
2401
  dependencies = [
2402
2402
  "bytes",
2403
2403
  "getrandom 0.3.2",
2404
- "rand 0.9.0",
2404
+ "rand 0.9.1",
2405
2405
  "ring",
2406
2406
  "rustc-hash 2.1.1",
2407
2407
  "rustls",
@@ -2466,13 +2466,12 @@ dependencies = [
2466
2466
 
2467
2467
  [[package]]
2468
2468
  name = "rand"
2469
- version = "0.9.0"
2469
+ version = "0.9.1"
2470
2470
  source = "registry+https://github.com/rust-lang/crates.io-index"
2471
- checksum = "3779b94aeb87e8bd4e834cee3650289ee9e0d5677f976ecdb6d219e5f4f6cd94"
2471
+ checksum = "9fbfd9d094a40bf3ae768db9361049ace4c0e04a4fd6b359518bd7b73a73dd97"
2472
2472
  dependencies = [
2473
2473
  "rand_chacha 0.9.0",
2474
2474
  "rand_core 0.9.3",
2475
- "zerocopy",
2476
2475
  ]
2477
2476
 
2478
2477
  [[package]]
@@ -3062,9 +3061,9 @@ checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64"
3062
3061
 
3063
3062
  [[package]]
3064
3063
  name = "signal-hook-registry"
3065
- version = "1.4.2"
3064
+ version = "1.4.5"
3066
3065
  source = "registry+https://github.com/rust-lang/crates.io-index"
3067
- checksum = "a9e9e0b4211b72e7b8b6e85c807d36c212bdb33ea8587f7569562a84df5465b1"
3066
+ checksum = "9203b8055f63a2a00e2f593bb0510367fe707d7ff1e5c872de2f537b339e5410"
3068
3067
  dependencies = [
3069
3068
  "libc",
3070
3069
  ]
@@ -1,6 +1,6 @@
1
1
  [package]
2
2
  name = "itsi-scheduler"
3
- version = "0.2.2"
3
+ version = "0.2.3"
4
4
  edition = "2021"
5
5
  authors = ["Wouter Coppieters <wc@pico.net.nz>"]
6
6
  license = "MIT"
@@ -1,6 +1,6 @@
1
1
  [package]
2
2
  name = "itsi-server"
3
- version = "0.2.2"
3
+ version = "0.2.3"
4
4
  edition = "2021"
5
5
  authors = ["Wouter Coppieters <wc@pico.net.nz>"]
6
6
  license = "MIT"
@@ -14,7 +14,7 @@ use magnus::{
14
14
  block::Proc,
15
15
  error::Result,
16
16
  value::{LazyId, ReprValue},
17
- RArray, RHash, Ruby, Symbol, Value,
17
+ RArray, RHash, Ruby, Symbol, TryConvert, Value,
18
18
  };
19
19
  use nix::{
20
20
  fcntl::{fcntl, FcntlArg, FdFlag},
@@ -124,9 +124,17 @@ impl ServerParams {
124
124
  debug!("Loading Itsi Scheduler");
125
125
  ruby.require("itsi/scheduler")?;
126
126
  }
127
- let routes_raw = self
127
+ let result_pair = self
128
128
  .middleware_loader
129
- .call::<_, Option<Value>>(())
129
+ .call::<(), RArray>(())
130
+ .inspect_err(|e| {
131
+ eprintln!("Error loading middleware: {:?}", e);
132
+ if let Some(err_value) = e.value() {
133
+ print_rb_backtrace(err_value);
134
+ }
135
+ })?;
136
+ let routes_raw = result_pair
137
+ .entry::<Option<Value>>(0)
130
138
  .inspect_err(|e| {
131
139
  eprintln!("Error loading middleware: {:?}", e);
132
140
  if let Some(err_value) = e.value() {
@@ -134,6 +142,21 @@ impl ServerParams {
134
142
  }
135
143
  })?
136
144
  .map(|mw| mw.into());
145
+ let error_lines = result_pair.entry::<Option<RArray>>(1).inspect_err(|e| {
146
+ eprintln!("Error loading middleware: {:?}", e);
147
+ if let Some(err_value) = e.value() {
148
+ print_rb_backtrace(err_value);
149
+ }
150
+ })?;
151
+ if error_lines.is_some_and(|r| !r.is_empty()) {
152
+ let errors: Vec<String> =
153
+ Vec::<String>::try_convert(error_lines.unwrap().as_value())?;
154
+ ItsiServerConfig::print_config_errors(errors);
155
+ return Err(magnus::Error::new(
156
+ magnus::exception::runtime_error(),
157
+ "Failed to set middleware",
158
+ ));
159
+ }
137
160
  let middleware = MiddlewareSet::new(routes_raw)?;
138
161
  self.middleware.set(middleware).map_err(|_| {
139
162
  magnus::Error::new(
@@ -3,7 +3,7 @@
3
3
  require "stringio"
4
4
  require "socket"
5
5
  require "uri"
6
- require_relative 'http_request/response_status_shortcodes'
6
+ require_relative "http_request/response_status_shortcodes"
7
7
 
8
8
  module Itsi
9
9
  class HttpRequest
@@ -22,7 +22,7 @@ module Itsi
22
22
  end
23
23
  [header, rack_form]
24
24
  end.to_h.tap do |hm|
25
- hm.default_proc = proc { |hsh, key| "HTTP_#{key.upcase.gsub(/-/, "_")}" }
25
+ hm.default_proc = proc { |_, key| "HTTP_#{key.upcase.gsub(/-/, "_")}" }
26
26
  end
27
27
 
28
28
  def to_rack_env
@@ -78,7 +78,7 @@ module Itsi
78
78
  end
79
79
 
80
80
  def respond(
81
- _body = nil, _status = 200, _headers = nil,
81
+ _body = nil, _status = 200, _headers = nil, # rubocop:disable Lint/UnderscorePrefixedVariableName
82
82
  json: nil,
83
83
  html: nil,
84
84
  text: nil,
@@ -90,13 +90,12 @@ module Itsi
90
90
  body: _body,
91
91
  &blk
92
92
  )
93
-
94
93
  if json
95
94
  if as
96
95
  begin
97
96
  validate!(json, as: as)
98
97
  rescue ValidationError => e
99
- json = {type: 'error', message: "Validation Error: #{e.message}"}
98
+ json = { type: "error", message: "Validation Error: #{e.message}" }
100
99
  status = 400
101
100
  end
102
101
  end
@@ -118,15 +117,13 @@ module Itsi
118
117
  end
119
118
 
120
119
  response.respond(status: status, headers: headers, body: body, hijack: hijack, &blk)
121
-
122
-
123
120
  end
124
121
 
125
122
  def hijack
126
123
  self.hijacked = true
127
124
  UNIXSocket.pair.yield_self do |(server_sock, app_sock)|
128
125
  server_sock.autoclose = false
129
- self.response.hijack(server_sock.fileno)
126
+ response.hijack(server_sock.fileno)
130
127
  server_sock.sync = true
131
128
  app_sock.sync = true
132
129
  app_sock
@@ -150,37 +147,37 @@ module Itsi
150
147
  as ? apply_schema!(params, as) : params
151
148
  end
152
149
 
153
- def params(schema=nil)
154
- params = case
155
- when url_encoded? then URI.decode_www_form(build_input_io.read).to_h
156
- when json? then JSON.parse(build_input_io.read)
157
- when multipart?
158
- Rack::Multipart::Parser.parse(
159
- build_input_io,
160
- content_length,
161
- content_type,
162
- Rack::Multipart::Parser::TEMPFILE_FACTORY,
163
- Rack::Multipart::Parser::BUFSIZE,
164
- Rack::Utils.default_query_parser
165
- ).params
166
- else
167
- {}
168
- end
150
+ def params(schema = nil)
151
+ params = if url_encoded?
152
+ URI.decode_www_form(build_input_io.read).to_h
153
+ elsif json?
154
+ JSON.parse(build_input_io.read)
155
+ elsif multipart?
156
+ Rack::Multipart::Parser.parse(
157
+ build_input_io,
158
+ content_length,
159
+ content_type,
160
+ Rack::Multipart::Parser::TEMPFILE_FACTORY,
161
+ Rack::Multipart::Parser::BUFSIZE,
162
+ Rack::Utils.default_query_parser
163
+ ).params
164
+ else
165
+ {}
166
+ end
169
167
 
170
168
  params.merge!(query_params).merge!(url_params)
171
169
  validated = schema ? apply_schema!(params, schema) : params
172
- unless block_given?
173
- if multipart?
174
- raise "#params must take a block for multipart requests"
175
- else
176
- return validated
177
- end
178
- else
170
+ if block_given?
179
171
  yield validated
172
+ else
173
+ raise "#params must take a block for multipart requests" if multipart?
174
+
175
+ validated
176
+
180
177
  end
181
178
  rescue ValidationError => e
182
179
  if response.json?
183
- respond(json: {error: e.message}, status: 400)
180
+ respond(json: { error: e.message }, status: 400)
184
181
  else
185
182
  respond(e.message, 400)
186
183
  end
@@ -191,7 +188,7 @@ module Itsi
191
188
  # Unexpected error.
192
189
  # Don't reveal potential sensitive information to client.
193
190
  if response.json?
194
- respond(json: {error: "Internal Server Error"}, status: 500)
191
+ respond(json: { error: "Internal Server Error" }, status: 500)
195
192
  else
196
193
  respond("Internal Server Error", 500)
197
194
  end
@@ -205,7 +202,7 @@ module Itsi
205
202
  if params.key?(:tempfile)
206
203
  params[:tempfile].unlink
207
204
  else
208
- params.each_value { |v| clean_temp_files(v) }
205
+ params.each_value { |v| clean_temp_files(v) }
209
206
  end
210
207
  when Array then params.each { |v| clean_temp_files(v) }
211
208
  end
@@ -1,15 +1,17 @@
1
1
  # frozen_string_literal: true
2
- require 'forwardable'
2
+
3
+ require "forwardable"
3
4
  require "stringio"
4
5
  require "socket"
5
6
 
6
7
  module Itsi
7
-
8
8
  class HttpResponse
9
-
10
- def respond _body=nil, _status=200, _header=nil, status: _status, headers: _header, body: _body, hijack: false, &blk
11
-
12
- self.status = status.kind_of?(Symbol) ? HTTP_STATUS_NAME_TO_CODE_MAP.fetch(status) : status.to_i
9
+ def respond(
10
+ _body = nil, _status = 200, _header = nil, # rubocop:disable Lint/UnderscorePrefixedVariableName
11
+ status: _status, headers: _header, body: _body,
12
+ hijack: false
13
+ )
14
+ self.status = status.is_a?(Symbol) ? HTTP_STATUS_NAME_TO_CODE_MAP.fetch(status) : status.to_i
13
15
 
14
16
  body = body.to_s unless body.is_a?(String)
15
17
 
@@ -33,9 +35,9 @@ module Itsi
33
35
 
34
36
  # If you hijack the connection, you are responsible for closing it.
35
37
  # Otherwise, the response will be closed automatically.
36
- self.close unless hijack
38
+ close unless hijack
37
39
  else
38
- self.close
40
+ close
39
41
  end
40
42
  end
41
43
  end
data/lib/itsi/passfile.rb CHANGED
@@ -1,8 +1,7 @@
1
1
  module Itsi
2
2
  class Server
3
-
4
3
  module Passfile
5
- require 'io/console'
4
+ require "io/console"
6
5
 
7
6
  module_function
8
7
 
@@ -18,7 +17,7 @@ module Itsi
18
17
  line.chomp!
19
18
  next if line.empty?
20
19
 
21
- user, pass = line.split(':', 2)
20
+ user, pass = line.split(":", 2)
22
21
  creds[user] = pass
23
22
  end
24
23
  end
@@ -26,14 +25,14 @@ module Itsi
26
25
  end
27
26
 
28
27
  def save(creds, filename)
29
- File.open(filename, 'w', 0o600) do |f|
28
+ File.open(filename, "w", 0o600) do |f|
30
29
  creds.each do |u, p|
31
30
  f.puts "#{u}:#{p}"
32
31
  end
33
32
  end
34
33
  end
35
34
 
36
- def echo(filename, algorithm)
35
+ def echo(_, algorithm)
37
36
  print "Enter username: "
38
37
  username = $stdin.gets.chomp
39
38
 
@@ -56,6 +55,7 @@ module Itsi
56
55
 
57
56
  def add(filename, algorithm)
58
57
  return unless (creds = load(filename))
58
+
59
59
  print "Enter username: "
60
60
  username = $stdin.gets.chomp
61
61
 
@@ -98,11 +98,11 @@ module Itsi
98
98
  def list(filename)
99
99
  puts "Current credentials in '#{filename}':"
100
100
  return unless (creds = load(filename))
101
+
101
102
  creds.each do |u, p|
102
103
  puts "#{u}:#{p}"
103
104
  end
104
105
  end
105
-
106
106
  end
107
107
  end
108
108
  end
@@ -2,7 +2,6 @@ module Itsi
2
2
  class Server
3
3
  module Config
4
4
  module ConfigHelpers
5
-
6
5
  def self.load_and_register(klass)
7
6
  config_type = klass.name.split("::").last.downcase.gsub(/([a-z]()[A-Z])/, '\1_\2')
8
7
 
@@ -17,35 +16,35 @@ module Itsi
17
16
  following = klass.subclasses
18
17
  new_class = (following - current).first
19
18
 
20
- documentation_file = "#{file[/(.*)\.rb/,1]}.md"
21
- if ! File.exist?(documentation_file)
22
- documentation_file = "#{file[/(.*)\/[^\/]+\.rb/,1]}/_index.md"
23
- end
24
- if File.exist?(documentation_file) && new_class
25
- new_class.documentation IO.read(documentation_file)
26
- .gsub(/^---.*?\n.*?-+/m,'') # Strip frontmatter
27
- .gsub(/^(```.*?)\{.*?\}.*$/, "\\1") # Strip filename from code blocks
28
- .gsub(/^\{\{[^\}]+\}\}/, "") # Strip Hugo blocks
29
- end
19
+ documentation_file = "#{file[/(.*)\.rb/, 1]}.md"
20
+ documentation_file = "#{file[%r{(.*)/[^/]+\.rb}, 1]}/_index.md" unless File.exist?(documentation_file)
21
+ next unless File.exist?(documentation_file) && new_class
22
+
23
+ new_class.documentation IO.read(documentation_file)
24
+ .gsub(/^---.*?\n.*?-+/m, "") # Strip frontmatter
25
+ .gsub(/^(```.*?)\{.*?\}.*$/, "\\1") # Strip filename from code blocks
26
+ .gsub(/^\{\{[^}]+\}\}/, "") # Strip Hugo blocks
30
27
  end
31
28
  end
32
29
 
33
- def normalize_keys!(hash, expected=[])
30
+ def normalize_keys!(hash, expected = [])
34
31
  hash.keys.each do |key|
35
32
  value = hash.delete(key)
36
33
  key = key.to_s.downcase.to_sym
37
34
  hash[key] = value
38
35
  raise "Unexpected key: #{key}" unless expected.include?(key)
36
+
39
37
  expected -= [key]
40
38
  end
41
- raise "Missing required keys: #{expected.join(', ')}" unless expected.empty?
39
+ raise "Missing required keys: #{expected.join(", ")}" unless expected.empty?
40
+
42
41
  hash
43
42
  end
44
43
 
45
- def self.included(cls)
46
- def cls.inherited(base)
44
+ def self.included(cls) # rubocop:disable Metrics/PerceivedComplexity,Metrics/AbcSize,Metrics/CyclomaticComplexity,Metrics/MethodLength
45
+ def cls.inherited(base) # rubocop:disable Metrics/MethodLength,Lint/MissingSuper,Metrics/PerceivedComplexity
47
46
  %i[detail documentation insert_text schema].each do |attr|
48
- base.define_singleton_method(attr) do |value=nil|
47
+ base.define_singleton_method(attr) do |value = nil|
49
48
  @middleware_class_attrs ||= {}
50
49
  if value
51
50
  @middleware_class_attrs[attr] = value
@@ -54,12 +53,12 @@ module Itsi
54
53
  end
55
54
  end
56
55
 
57
- base.define_method(attr) do |value=nil|
56
+ base.define_method(attr) do |_value = nil|
58
57
  self.class.send(attr)
59
58
  end
60
59
  end
61
60
 
62
- def base.schema(value=nil, &blk)
61
+ def base.schema(value = nil, &blk)
63
62
  @middleware_class_attrs ||= {}
64
63
  if blk
65
64
  @middleware_class_attrs[:schema] = TypedStruct.new(&blk)
@@ -75,29 +74,30 @@ module Itsi
75
74
 
76
75
  config_type = cls.name.split("::").last.downcase
77
76
 
78
- cls.define_singleton_method("#{config_type}_name") do |name=self.name|
77
+ cls.define_singleton_method("#{config_type}_name") do |name = self.name|
79
78
  @config_name ||= name.split("::").last.gsub(/([a-z])([A-Z])/, '\1_\2').downcase.to_sym
80
79
  end
81
- cls.define_method(:opt_name){ self.class.send("#{config_type}_name") }
82
- cls.define_method(:location){ @location }
80
+ cls.define_method(:opt_name) { self.class.send("#{config_type}_name") }
81
+ cls.define_method(:location) { @location }
83
82
  end
84
83
 
85
- def initialize(location, params={})
84
+ def initialize(location, params = {})
86
85
  if !self.class.ancestors.include?(Middleware) && !location.parent.nil?
87
86
  raise "#{opt_name} must be set at the top level"
88
87
  end
88
+
89
89
  @location = location
90
- @params = case self.schema
91
- when TypedStruct::Validation
92
- self.schema.validate!(params)
93
- when Array
94
- default, validation = self.schema
95
- params ? validation.validate!(params) : default
96
- when nil
97
- nil
98
- else
99
- self.schema.new(params).to_h
100
- end
90
+ @params = case schema
91
+ when TypedStruct::Validation
92
+ schema.validate!(params)
93
+ when Array
94
+ default, validation = schema
95
+ params ? validation.validate!(params) : default
96
+ when nil
97
+ nil
98
+ else
99
+ schema.new(params).to_h
100
+ end
101
101
  end
102
102
  end
103
103
  end