spikard 0.2.5 → 0.3.1
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/LICENSE +1 -1
- data/README.md +659 -626
- data/ext/spikard_rb/Cargo.toml +17 -17
- data/ext/spikard_rb/extconf.rb +10 -10
- data/ext/spikard_rb/src/lib.rs +6 -6
- data/lib/spikard/app.rb +386 -374
- data/lib/spikard/background.rb +27 -27
- data/lib/spikard/config.rb +396 -396
- data/lib/spikard/converters.rb +13 -85
- data/lib/spikard/handler_wrapper.rb +113 -116
- data/lib/spikard/provide.rb +214 -228
- data/lib/spikard/response.rb +173 -109
- data/lib/spikard/schema.rb +243 -243
- data/lib/spikard/sse.rb +111 -111
- data/lib/spikard/streaming_response.rb +44 -21
- data/lib/spikard/testing.rb +221 -221
- data/lib/spikard/upload_file.rb +131 -131
- data/lib/spikard/version.rb +5 -5
- data/lib/spikard/websocket.rb +59 -59
- data/lib/spikard.rb +43 -43
- data/sig/spikard.rbs +360 -349
- data/vendor/bundle/ruby/3.4.0/gems/rake-compiler-dock-1.10.0/build/buildkitd.toml +2 -0
- metadata +5 -85
- data/vendor/crates/spikard-core/Cargo.toml +0 -40
- data/vendor/crates/spikard-core/src/bindings/mod.rs +0 -3
- data/vendor/crates/spikard-core/src/bindings/response.rs +0 -133
- data/vendor/crates/spikard-core/src/debug.rs +0 -63
- data/vendor/crates/spikard-core/src/di/container.rs +0 -726
- data/vendor/crates/spikard-core/src/di/dependency.rs +0 -273
- data/vendor/crates/spikard-core/src/di/error.rs +0 -118
- data/vendor/crates/spikard-core/src/di/factory.rs +0 -538
- data/vendor/crates/spikard-core/src/di/graph.rs +0 -545
- data/vendor/crates/spikard-core/src/di/mod.rs +0 -192
- data/vendor/crates/spikard-core/src/di/resolved.rs +0 -411
- data/vendor/crates/spikard-core/src/di/value.rs +0 -283
- data/vendor/crates/spikard-core/src/http.rs +0 -153
- data/vendor/crates/spikard-core/src/lib.rs +0 -28
- data/vendor/crates/spikard-core/src/lifecycle.rs +0 -422
- data/vendor/crates/spikard-core/src/parameters.rs +0 -719
- data/vendor/crates/spikard-core/src/problem.rs +0 -310
- data/vendor/crates/spikard-core/src/request_data.rs +0 -189
- data/vendor/crates/spikard-core/src/router.rs +0 -249
- data/vendor/crates/spikard-core/src/schema_registry.rs +0 -183
- data/vendor/crates/spikard-core/src/type_hints.rs +0 -304
- data/vendor/crates/spikard-core/src/validation.rs +0 -699
- data/vendor/crates/spikard-http/Cargo.toml +0 -58
- data/vendor/crates/spikard-http/src/auth.rs +0 -247
- data/vendor/crates/spikard-http/src/background.rs +0 -249
- data/vendor/crates/spikard-http/src/bindings/mod.rs +0 -3
- data/vendor/crates/spikard-http/src/bindings/response.rs +0 -1
- data/vendor/crates/spikard-http/src/body_metadata.rs +0 -8
- data/vendor/crates/spikard-http/src/cors.rs +0 -490
- data/vendor/crates/spikard-http/src/debug.rs +0 -63
- data/vendor/crates/spikard-http/src/di_handler.rs +0 -423
- data/vendor/crates/spikard-http/src/handler_response.rs +0 -190
- data/vendor/crates/spikard-http/src/handler_trait.rs +0 -228
- data/vendor/crates/spikard-http/src/handler_trait_tests.rs +0 -284
- data/vendor/crates/spikard-http/src/lib.rs +0 -529
- data/vendor/crates/spikard-http/src/lifecycle/adapter.rs +0 -149
- data/vendor/crates/spikard-http/src/lifecycle.rs +0 -428
- data/vendor/crates/spikard-http/src/middleware/mod.rs +0 -285
- data/vendor/crates/spikard-http/src/middleware/multipart.rs +0 -86
- data/vendor/crates/spikard-http/src/middleware/urlencoded.rs +0 -147
- data/vendor/crates/spikard-http/src/middleware/validation.rs +0 -287
- data/vendor/crates/spikard-http/src/openapi/mod.rs +0 -309
- data/vendor/crates/spikard-http/src/openapi/parameter_extraction.rs +0 -190
- data/vendor/crates/spikard-http/src/openapi/schema_conversion.rs +0 -308
- data/vendor/crates/spikard-http/src/openapi/spec_generation.rs +0 -195
- data/vendor/crates/spikard-http/src/parameters.rs +0 -1
- data/vendor/crates/spikard-http/src/problem.rs +0 -1
- data/vendor/crates/spikard-http/src/query_parser.rs +0 -369
- data/vendor/crates/spikard-http/src/response.rs +0 -399
- data/vendor/crates/spikard-http/src/router.rs +0 -1
- data/vendor/crates/spikard-http/src/schema_registry.rs +0 -1
- data/vendor/crates/spikard-http/src/server/handler.rs +0 -80
- data/vendor/crates/spikard-http/src/server/lifecycle_execution.rs +0 -98
- data/vendor/crates/spikard-http/src/server/mod.rs +0 -805
- data/vendor/crates/spikard-http/src/server/request_extraction.rs +0 -119
- data/vendor/crates/spikard-http/src/sse.rs +0 -447
- data/vendor/crates/spikard-http/src/testing/form.rs +0 -14
- data/vendor/crates/spikard-http/src/testing/multipart.rs +0 -60
- data/vendor/crates/spikard-http/src/testing/test_client.rs +0 -285
- data/vendor/crates/spikard-http/src/testing.rs +0 -377
- data/vendor/crates/spikard-http/src/type_hints.rs +0 -1
- data/vendor/crates/spikard-http/src/validation.rs +0 -1
- data/vendor/crates/spikard-http/src/websocket.rs +0 -324
- data/vendor/crates/spikard-rb/Cargo.toml +0 -42
- data/vendor/crates/spikard-rb/build.rs +0 -8
- data/vendor/crates/spikard-rb/src/background.rs +0 -63
- data/vendor/crates/spikard-rb/src/config.rs +0 -294
- data/vendor/crates/spikard-rb/src/conversion.rs +0 -392
- data/vendor/crates/spikard-rb/src/di.rs +0 -409
- data/vendor/crates/spikard-rb/src/handler.rs +0 -534
- data/vendor/crates/spikard-rb/src/lib.rs +0 -2020
- data/vendor/crates/spikard-rb/src/lifecycle.rs +0 -267
- data/vendor/crates/spikard-rb/src/server.rs +0 -283
- data/vendor/crates/spikard-rb/src/sse.rs +0 -231
- data/vendor/crates/spikard-rb/src/test_client.rs +0 -404
- data/vendor/crates/spikard-rb/src/test_sse.rs +0 -143
- data/vendor/crates/spikard-rb/src/test_websocket.rs +0 -221
- data/vendor/crates/spikard-rb/src/websocket.rs +0 -233
- /data/vendor/bundle/ruby/{3.3.0 → 3.4.0}/gems/diff-lcs-1.6.2/mise.toml +0 -0
data/lib/spikard/response.rb
CHANGED
|
@@ -1,109 +1,173 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
#
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
end
|
|
31
|
-
|
|
32
|
-
def
|
|
33
|
-
@
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# ⚠️ GENERATED BY crates/spikard-rb/build.rs — DO NOT EDIT BY HAND
|
|
4
|
+
module Spikard
|
|
5
|
+
class Response # :nodoc: Native-backed HTTP response facade generated from Rust metadata.
|
|
6
|
+
attr_reader :content, :status_code, :headers, :native_response
|
|
7
|
+
|
|
8
|
+
def initialize(content: nil, body: nil, status_code: 200, headers: nil, content_type: nil)
|
|
9
|
+
@content = content.nil? ? body : content
|
|
10
|
+
@status_code = Integer(status_code || 200)
|
|
11
|
+
@headers = normalize_headers(headers)
|
|
12
|
+
set_header('content-type', content_type) if content_type
|
|
13
|
+
rebuild_native!
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def status
|
|
17
|
+
@status_code
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def status_code=(value)
|
|
21
|
+
@status_code = Integer(value)
|
|
22
|
+
rebuild_native!
|
|
23
|
+
rescue ArgumentError, TypeError
|
|
24
|
+
raise ArgumentError, 'status_code must be an integer'
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def headers=(value)
|
|
28
|
+
@headers = normalize_headers(value)
|
|
29
|
+
rebuild_native!
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def content=(value)
|
|
33
|
+
@content = value
|
|
34
|
+
rebuild_native!
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def set_header(name, value)
|
|
38
|
+
@headers[name.to_s] = value.to_s
|
|
39
|
+
rebuild_native!
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def set_cookie(name, value, **options)
|
|
43
|
+
raise ArgumentError, 'cookie name required' if name.nil? || name.empty?
|
|
44
|
+
|
|
45
|
+
header_value = ["#{name}=#{value}", *cookie_parts(options)].join('; ')
|
|
46
|
+
set_header('set-cookie', header_value)
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def to_native_response
|
|
50
|
+
@native_response
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
private
|
|
54
|
+
|
|
55
|
+
def rebuild_native!
|
|
56
|
+
ensure_native!
|
|
57
|
+
@native_response = Spikard::Native.build_response(@content, @status_code, @headers)
|
|
58
|
+
return unless @native_response
|
|
59
|
+
|
|
60
|
+
@status_code = @native_response.status_code
|
|
61
|
+
@headers = @native_response.headers
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
def ensure_native!
|
|
65
|
+
return if defined?(Spikard::Native) && Spikard::Native.respond_to?(:build_response)
|
|
66
|
+
|
|
67
|
+
raise 'Spikard native extension is not loaded'
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
def cookie_parts(options)
|
|
71
|
+
[
|
|
72
|
+
options[:max_age] && "Max-Age=#{Integer(options[:max_age])}",
|
|
73
|
+
options[:domain] && "Domain=#{options[:domain]}",
|
|
74
|
+
"Path=#{options.fetch(:path, '/') || '/'}",
|
|
75
|
+
options[:secure] ? 'Secure' : nil,
|
|
76
|
+
options[:httponly] ? 'HttpOnly' : nil,
|
|
77
|
+
options[:samesite] && "SameSite=#{options[:samesite]}"
|
|
78
|
+
].compact
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
def normalize_headers(value)
|
|
82
|
+
case value
|
|
83
|
+
when nil
|
|
84
|
+
{}
|
|
85
|
+
when Hash
|
|
86
|
+
value.each_with_object({}) do |(key, val), acc|
|
|
87
|
+
acc[key.to_s.downcase] = val.to_s
|
|
88
|
+
end
|
|
89
|
+
else
|
|
90
|
+
raise ArgumentError, 'headers must be a Hash'
|
|
91
|
+
end
|
|
92
|
+
end
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
class StreamingResponse # :nodoc: Streaming response wrapper backed by the native Rust builder.
|
|
96
|
+
attr_reader :stream, :status_code, :headers, :native_response
|
|
97
|
+
|
|
98
|
+
def initialize(stream, status_code: 200, headers: nil)
|
|
99
|
+
unless stream.respond_to?(:next) || stream.respond_to?(:each)
|
|
100
|
+
raise ArgumentError, 'StreamingResponse requires an object responding to #next or #each'
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
@stream = stream.respond_to?(:to_enum) ? stream.to_enum : stream
|
|
104
|
+
@status_code = Integer(status_code || 200)
|
|
105
|
+
header_hash = headers || {}
|
|
106
|
+
@headers = header_hash.each_with_object({}) do |(key, value), memo|
|
|
107
|
+
memo[String(key)] = String(value)
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
rebuild_native!
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
def to_native_response
|
|
114
|
+
@native_response
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
private
|
|
118
|
+
|
|
119
|
+
def rebuild_native!
|
|
120
|
+
ensure_native!
|
|
121
|
+
@native_response = Spikard::Native.build_streaming_response(@stream, @status_code, @headers)
|
|
122
|
+
return unless @native_response
|
|
123
|
+
|
|
124
|
+
@status_code = @native_response.status_code
|
|
125
|
+
@headers = @native_response.headers
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
def ensure_native!
|
|
129
|
+
return if defined?(Spikard::Native) && Spikard::Native.respond_to?(:build_streaming_response)
|
|
130
|
+
|
|
131
|
+
raise 'Spikard native extension is not loaded'
|
|
132
|
+
end
|
|
133
|
+
end
|
|
134
|
+
|
|
135
|
+
module Testing
|
|
136
|
+
class Response # :nodoc: Lightweight response wrapper used by the test client.
|
|
137
|
+
attr_reader :status_code, :headers, :body
|
|
138
|
+
|
|
139
|
+
def initialize(payload)
|
|
140
|
+
@status_code = payload[:status_code]
|
|
141
|
+
@headers = payload[:headers] || {}
|
|
142
|
+
@body = payload[:body]
|
|
143
|
+
@body_text = payload[:body_text]
|
|
144
|
+
end
|
|
145
|
+
|
|
146
|
+
def status
|
|
147
|
+
@status_code
|
|
148
|
+
end
|
|
149
|
+
|
|
150
|
+
def body_bytes
|
|
151
|
+
@body || ''.b
|
|
152
|
+
end
|
|
153
|
+
|
|
154
|
+
def body_text
|
|
155
|
+
@body_text || @body&.dup&.force_encoding(Encoding::UTF_8)
|
|
156
|
+
end
|
|
157
|
+
|
|
158
|
+
def text
|
|
159
|
+
body_text
|
|
160
|
+
end
|
|
161
|
+
|
|
162
|
+
def json
|
|
163
|
+
return nil if @body.nil? || @body.empty?
|
|
164
|
+
|
|
165
|
+
JSON.parse(@body)
|
|
166
|
+
end
|
|
167
|
+
|
|
168
|
+
def bytes
|
|
169
|
+
body_bytes.bytes
|
|
170
|
+
end
|
|
171
|
+
end
|
|
172
|
+
end
|
|
173
|
+
end
|