mortymer 0.0.11 → 0.0.12

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: 1aaae1b0260575ca60caeb8b676577f39766162d8127a6266e1c49e168e11265
4
- data.tar.gz: 0f92cfaa12e157dcb4954259dd284b7b46f7305dd912d84a55fef597107997f7
3
+ metadata.gz: e1733f673e867c239bda30efbc34f45f7452ebbee12a702e201dffbcbb02f621
4
+ data.tar.gz: 9ff44dd993b2ed7a82971437048731e80cb97b1a15d96fbdeb758d9797b6f3e4
5
5
  SHA512:
6
- metadata.gz: c5c3932bfb5b0daf315af6f8f4a1ef36b0a448229fd15b9c71f7c8699d8f41fcfeb8a5858686b55d6c7905628936908512e97537b6a5ec0024061f6b3f4bcd60
7
- data.tar.gz: df393725ff3c29b36ede225c046f8f27cbfea156f09917cd1976b8c3188f9dafa5e57e0aa0876a378f7afda62ab0ea06b17f500d0f46f6d8caae18c249c13acf
6
+ metadata.gz: cd31959f30b91390ad9c40efb0fd18154e78829057df484a4b67c8efc5630f0ce97b3bfc47bff4c557bed421226311c6ad5cab077e1aa89da24d9b193defba51
7
+ data.tar.gz: b9b604148b9ff54cde6cb26bc15d2752e2f8542a9df414cc1d9feb466d8f5e803697336fbfbffab1fb51d8de7b14a5c8a69f53ce3a50638b9df1e4fc36943814
@@ -27,6 +27,9 @@ When you include `Mortymer::DependenciesDsl`, you get access to the `inject` dir
27
27
  1. Create an instance variable `@user_repository`
28
28
  2. Automatically initialize it with an instance of `UserRepository`
29
29
 
30
+ The name of the injected variable is the snake_case version of the class we are injecting by default. So
31
+ for example `Repositories::UserRepository` will result in an instance variable called `@user_repository`
32
+
30
33
  ### Custom Variable Names
31
34
 
32
35
  You can customize the instance variable name using the `as` option:
@@ -66,54 +69,61 @@ end
66
69
 
67
70
  ## Advanced Usage
68
71
 
69
- ### Dependency Scopes
70
-
71
- Mortymer supports different scopes for dependencies:
72
-
73
- #### Singleton Scope (Default)
74
-
75
- By default, dependencies are singleton-scoped, meaning the same instance is shared across the application:
72
+ Just with the basic information, Mortymer already provides a really powerful and
73
+ expressive system to declare dependencies, but as it is, is just a Fancy Factory or Initializer
74
+ for your classes. Where Dependency Injection really shines, is when you are able to control some
75
+ other aspects of the dependency injection cycle. For example, Mortymer does not interfere with your
76
+ usual object initialization.
76
77
 
77
78
  ```ruby
78
- class UserService
79
+ class MyService
79
80
  include Mortymer::DependenciesDsl
81
+ inject Mailer
80
82
 
81
- inject UserRepository # Singleton by default
82
- end
83
+ def initialize(user)
84
+ # At this point we can be sure that the @mailer instance
85
+ # is already defined
86
+ @mailer.send_email("Hello user", user.email)
87
+ @user = user
88
+ end
83
89
  ```
84
90
 
85
- #### Request Scope
91
+ It might not be clear what is happening here. What is really doing Mortymer is
92
+ wrapping the `#initialize` method with the dependency resolving algorithm and if
93
+ any `kwarg` passed to the `#initialize` method matches the name of the injected
94
+ dependency, then Mortymer will use that as the dependency instead.
86
95
 
87
- For dependencies that should be unique per request:
96
+ This means that you can call your previous service as:
88
97
 
89
98
  ```ruby
90
- class UserService
91
- include Mortymer::DependenciesDsl
92
-
93
- inject UserRepository, scope: :request
94
- end
99
+ MyService.new(User.first) # will use the Mailer class to instantiate the @mailer variable
100
+ MyService.new(User.first, mailer: instance_double(Mailer)) # will override @mailer with an instance_double
95
101
  ```
96
102
 
97
- #### Transient Scope
103
+ ### Dependency Scopes
98
104
 
99
- For dependencies that should be newly instantiated every time:
105
+ Mortymer supports different scopes for dependencies:
100
106
 
101
- ```ruby
102
- class UserService
103
- include Mortymer::DependenciesDsl
107
+ - By default, dependencies are transient, meaning you will get a new fresh instance each time you ask for one
108
+ - Dependencies might be singleton, meaning each injection will provide the same instance
109
+ - Dependencies might be lazy, basically, a block that might compute a value for your dependency
104
110
 
105
- inject UserRepository, scope: :transient
106
- end
107
- ```
111
+ To change a dependency's scope, you need to register it in the Mortymer DI Container
108
112
 
109
- ### Factory Registration
113
+ #### Singleton Scope
110
114
 
111
- You can register custom factory methods for your dependencies:
115
+ ```ruby
116
+ Mortymer.container.register_constant(Mailer, SingletonMailer.new)
117
+ ```
118
+
119
+ #### Lazy Scope
112
120
 
113
121
  ```ruby
114
- Mortymer.configure do |config|
115
- config.register_factory(UserRepository) do
116
- UserRepository.new(connection: DatabaseConnection.current)
122
+ Mortymer.container.register_constant(MAILER_ADMIN_ADDRESS) do
123
+ if some_condition?
124
+ "admin+#{Time.current}@example.com"
125
+ else
126
+ "admin-ex@example.com"
117
127
  end
118
128
  end
119
129
  ```
@@ -129,6 +139,12 @@ module UserRepositoryInterface
129
139
  end
130
140
  end
131
141
 
142
+ class UserService
143
+ include Mortymer::DependenciesDsl
144
+
145
+ inject UserRepositoryInterface, as: :repo
146
+ end
147
+
132
148
  class PostgresUserRepository
133
149
  include UserRepositoryInterface
134
150
  # implementation
@@ -140,259 +156,9 @@ class MongoUserRepository
140
156
  end
141
157
 
142
158
  # Register implementation
143
- Mortymer.configure do |config|
144
- config.register_implementation(UserRepositoryInterface, PostgresUserRepository)
145
- end
146
-
147
- class UserService
148
- include Mortymer::DependenciesDsl
149
-
150
- inject UserRepositoryInterface
151
- end
152
- ```
153
-
154
- ## Testing
155
-
156
- ### Mocking Dependencies
157
-
158
- Mortymer makes it easy to mock dependencies in tests:
159
-
160
- ```ruby
161
- RSpec.describe UserService do
162
- let(:repository_mock) { instance_double(UserRepository) }
163
- let(:mailer_mock) { instance_double(UserMailer) }
164
-
165
- before do
166
- Mortymer.stub_dependency(UserRepository, repository_mock)
167
- Mortymer.stub_dependency(UserMailer, mailer_mock)
168
- end
169
-
170
- it "creates a user" do
171
- service = UserService.new
172
- expect(repository_mock).to receive(:create)
173
- expect(mailer_mock).to receive(:send_welcome_email)
174
-
175
- service.create_user(name: "John")
176
- end
177
- end
178
- ```
179
-
180
- ### Test-Specific Implementations
181
-
182
- You can also register test-specific implementations:
183
-
184
- ```ruby
185
- class TestUserRepository
186
- include UserRepositoryInterface
187
-
188
- def initialize
189
- @users = {}
190
- end
191
-
192
- def find(id)
193
- @users[id]
194
- end
195
- end
196
-
197
- RSpec.describe UserService do
198
- before do
199
- Mortymer.register_implementation(UserRepositoryInterface, TestUserRepository)
200
- end
201
- end
202
- ```
203
-
204
- ## Best Practices
205
-
206
- ### 1. Keep Dependencies Explicit
207
-
208
- Always use explicit constant references rather than strings for dependencies:
209
-
210
- ```ruby
211
- # Good
212
- inject UserRepository
213
-
214
- # Avoid
215
- inject "user_repository"
216
- ```
217
-
218
- ### 2. Use Meaningful Names
219
-
220
- Choose descriptive names for your dependencies:
221
-
222
- ```ruby
223
- # Good
224
- inject UserRepository, as: :active_users_repository
225
-
226
- # Less Clear
227
- inject UserRepository, as: :repo
228
- ```
229
-
230
- ### 3. Group Related Dependencies
231
-
232
- Keep related dependencies together and organize them logically:
233
-
234
- ```ruby
235
- class UserService
236
- include Mortymer::DependenciesDsl
237
-
238
- # Authentication dependencies
239
- inject AuthenticationService
240
- inject TokenGenerator
241
-
242
- # User management dependencies
243
- inject UserRepository
244
- inject UserMailer
159
+ Mortymer.container.register_constant(UserRepositoryInterface, PostgresUserRepository.new)
245
160
 
246
- # Logging/Monitoring
247
- inject Logger
248
- inject MetricsCollector
249
- end
250
- ```
251
-
252
- ### 4. Interface Segregation
253
-
254
- Create focused interfaces for your dependencies:
255
-
256
- ```ruby
257
- module UserReader
258
- def find(id); end
259
- def list; end
260
- end
261
-
262
- module UserWriter
263
- def create(attributes); end
264
- def update(id, attributes); end
265
- end
266
-
267
- class UserRepository
268
- include UserReader
269
- include UserWriter
270
- end
271
-
272
- class UserService
273
- include Mortymer::DependenciesDsl
274
-
275
- inject UserReader # Only inject what you need
276
- end
277
- ```
278
-
279
- ## Common Patterns
280
-
281
- ### Service Objects
282
-
283
- ```ruby
284
- class CreateUser
285
- include Mortymer::DependenciesDsl
286
-
287
- inject UserRepository
288
- inject UserMailer
289
- inject UserValidator
290
-
291
- def call(params)
292
- @user_validator.validate!(params)
293
- user = @user_repository.create(params)
294
- @user_mailer.send_welcome_email(user)
295
- user
296
- end
297
- end
298
- ```
299
-
300
- ### Decorators
301
-
302
- ```ruby
303
- class LoggedUserRepository
304
- include Mortymer::DependenciesDsl
305
-
306
- inject UserRepository
307
- inject Logger
308
-
309
- def find(id)
310
- @logger.info("Finding user: #{id}")
311
- result = @user_repository.find(id)
312
- @logger.info("Found user: #{result&.id}")
313
- result
314
- end
315
- end
316
- ```
317
-
318
- ## Configuration
319
-
320
- ### Global Configuration
321
-
322
- ```ruby
323
- Mortymer.configure do |config|
324
- # Register default implementations
325
- config.register_implementation(UserRepositoryInterface, PostgresUserRepository)
326
-
327
- # Register factories
328
- config.register_factory(Logger) do
329
- Logger.new($stdout).tap do |logger|
330
- logger.level = Rails.env.production? ? :info : :debug
331
- end
332
- end
333
-
334
- # Configure scopes
335
- config.set_scope(UserSession, :request)
336
- end
337
- ```
338
-
339
- ### Environment-Specific Configuration
340
-
341
- ```ruby
342
- # config/initializers/mortymer.rb
343
- Mortymer.configure do |config|
344
- if Rails.env.test?
345
- config.register_implementation(UserRepositoryInterface, TestUserRepository)
346
- elsif Rails.env.development?
347
- config.register_implementation(UserRepositoryInterface, DevUserRepository)
348
- else
349
- config.register_implementation(UserRepositoryInterface, ProductionUserRepository)
350
- end
351
- end
161
+ # Then you can instantiate
162
+ UserService.new # will use the PostgresUserRepository implementation
163
+ UserService.new(repo: MongoUserRepository.new) # override the dependency to use a different one
352
164
  ```
353
-
354
- ## Troubleshooting
355
-
356
- ### Common Issues
357
-
358
- 1. **Circular Dependencies**
359
-
360
- ```ruby
361
- # This will raise a CircularDependencyError
362
- class UserService
363
- include Mortymer::DependenciesDsl
364
- inject AccountService
365
- end
366
-
367
- class AccountService
368
- include Mortymer::DependenciesDsl
369
- inject UserService # Circular dependency!
370
- end
371
- ```
372
-
373
- Solution: Refactor to remove the circular dependency or use method injection.
374
-
375
- 2. **Missing Dependencies**
376
-
377
- ```ruby
378
- # This will raise a DependencyNotFoundError
379
- class UserService
380
- include Mortymer::DependenciesDsl
381
- inject NonExistentService
382
- end
383
- ```
384
-
385
- Solution: Ensure all dependencies are properly registered or the constants exist.
386
-
387
- 3. **Scope Conflicts**
388
-
389
- ```ruby
390
- # This might cause issues
391
- class UserService
392
- include Mortymer::DependenciesDsl
393
- inject SessionManager, scope: :request # Request-scoped
394
- inject UserRepository # Singleton-scoped
395
- end
396
- ```
397
-
398
- Solution: Be careful mixing different scopes and ensure it makes sense for your use case.
@@ -0,0 +1,208 @@
1
+ # Mortymer Type System Guide
2
+
3
+ ## Overview
4
+
5
+ Mortymer provides a way to enforce the types contracts for inputs and
6
+ outputs of your methods through the `Sigil` module that leverages `dry-types`
7
+ to enable runtime type checking. Not only that, but, it also will try to coerce
8
+ the given parameters to the declared type, and will check validation contracts
9
+ and rules for your inputs and outputs. This is not intended to be a replacement
10
+ for Type Checkers like Sorbet or Steep, but rather a nice utility to avoid guard
11
+ code like:
12
+
13
+ ```ruby
14
+ def func(params)
15
+ result = MyContract.new.call(params)
16
+ if result.errors.empty?
17
+ result[:age].to_i + 10
18
+ else
19
+ raise StandardError, result.errors
20
+ end
21
+ end
22
+ ```
23
+
24
+ The above snippet is really common when dealing with validation (you may use `#instance_of?` method as well,
25
+ or strong parameters or whatever, but the essence is that you need to declare the shape of the data
26
+ that comes in and out of your methods).
27
+
28
+ Using Mortymer's Sigil, the above will translate to pretty much the following code:
29
+
30
+ ```ruby
31
+ sign MyContract
32
+ def func(params)
33
+ params.age + 10
34
+ end
35
+
36
+ func(MyContract.structify({age: 10})) # Will work
37
+ func(age: 10) # Will work, the params would be { age: 10 } which will be coerced and validated with MyCotnract
38
+ func(age: "10") # Will also work, if MyContract is Coercing the age to Integer
39
+ func(age: "asd") # will raise a meaningful error
40
+ ```
41
+
42
+ ## Basic Usage
43
+
44
+ ### Method Type Signatures
45
+
46
+ The most basic form of type checking in Mortymer uses the `sign` directive:
47
+
48
+ ```ruby
49
+ class Calculator
50
+ include Mortymer::Sigil
51
+
52
+ sign Types::Integer, Types::Integer, returns: Types::Integer
53
+ def add(a, b)
54
+ a + b
55
+ end
56
+ end
57
+ ```
58
+
59
+ When you include `Mortymer::Sigil`, you get access to the `sign` directive. This will:
60
+
61
+ 1. Check the types of all arguments when the method is called
62
+ 2. Verify the return type matches the specified type
63
+ 3. Raise a `TypeError` if any type mismatch occurs
64
+
65
+ ### Keyword Arguments
66
+
67
+ You can specify types for keyword arguments using a hash syntax:
68
+
69
+ ```ruby
70
+ class UserService
71
+ include Mortymer::Sigil
72
+
73
+ sign name: Types::String, age: Types::Integer, returns: Types::Hash
74
+ def create_user(name:, age:)
75
+ { name: name, age: age }
76
+ end
77
+ end
78
+ ```
79
+
80
+ ### Array Types
81
+
82
+ Mortymer supports type checking for arrays of specific types:
83
+
84
+ ```ruby
85
+ class Calculator
86
+ include Mortymer::Sigil
87
+
88
+ sign Types::Array.of(Types::Integer), returns: Types::Integer
89
+ def sum(numbers)
90
+ numbers.sum
91
+ end
92
+ end
93
+ ```
94
+
95
+ ## Advanced Usage
96
+
97
+ ### Contract Integration
98
+
99
+ Mortymer's type system integrates seamlessly with Contracts for more complex validations:
100
+
101
+ ```ruby
102
+ class AgeContract < Mortymer::Contract
103
+ params do
104
+ required(:age).value(Integer, gt?: 10)
105
+ end
106
+ compile!
107
+ end
108
+
109
+ class UserService
110
+ include Mortymer::Sigil
111
+
112
+ sign AgeContract, returns: Types::Hash
113
+ def process_age(params)
114
+ { processed_age: params.age * 2 }
115
+ end
116
+ end
117
+ ```
118
+
119
+ ### Model Integration
120
+
121
+ The type system works directly with Mortymer Models:
122
+
123
+ ```ruby
124
+ class User < Mortymer::Model
125
+ attribute :name, String
126
+ attribute :age, Integer
127
+ end
128
+
129
+ class UserService
130
+ include Mortymer::Sigil
131
+
132
+ sign User, returns: User
133
+ def double_age(user)
134
+ User.new(name: user.name, age: user.age * 2)
135
+ end
136
+ end
137
+ ```
138
+
139
+ ### Optional Return Types
140
+
141
+ You can omit the return type if you don't want to enforce it:
142
+
143
+ ```ruby
144
+ class StringService
145
+ include Mortymer::Sigil
146
+
147
+ sign Types::String
148
+ def uppercase(str)
149
+ str.upcase
150
+ end
151
+ end
152
+ ```
153
+
154
+ ### Type Coercion
155
+
156
+ The type system will attempt to coerce values when possible:
157
+
158
+ ```ruby
159
+ class UserService
160
+ include Mortymer::Sigil
161
+
162
+ sign User, returns: User
163
+ def process_user(user_data)
164
+ # Will coerce a hash into a User model
165
+ user = user_data.is_a?(User) ? user_data : User.new(user_data)
166
+ User.new(name: user.name.upcase, age: user.age)
167
+ end
168
+ end
169
+ ```
170
+
171
+ ## Error Handling
172
+
173
+ When type checking fails, Mortymer raises descriptive errors:
174
+
175
+ - `Mortymer::Sigil::TypeError` for type mismatches
176
+ - `Mortymer::Contract::ContractError` for contract violations
177
+
178
+ Example error messages:
179
+
180
+ - "Invalid type for argument 0: expected Integer, got String"
181
+ - "Invalid type for keyword argument name: expected String, got Integer"
182
+ - "Invalid return type: expected String, got Integer"
183
+
184
+ ## Best Practices
185
+
186
+ 1. **Be Explicit**: Always specify types for critical method parameters
187
+ 2. **Use Contracts**: For complex validations, combine with Mortymer Contracts
188
+ 3. **Return Types**: Specify return types when the output type is important
189
+ 4. **Model Integration**: Use Mortymer Models for structured data
190
+ 5. **Error Handling**: Handle type errors at appropriate boundaries in your application
191
+
192
+ ## Type System Compatibility
193
+
194
+ The type system maintains compatibility with other method hooks and Ruby features:
195
+
196
+ ```ruby
197
+ class Service
198
+ include Mortymer::Sigil
199
+ include OtherModule # with method_added hooks
200
+
201
+ sign Types::String, returns: Types::String
202
+ def process(str)
203
+ str.upcase
204
+ end
205
+ end
206
+ ```
207
+
208
+ The type system will properly chain method hooks while maintaining type checking functionality.
@@ -4,12 +4,14 @@ require_relative "dry_swagger"
4
4
  require_relative "endpoint_registry"
5
5
  require_relative "endpoint"
6
6
  require_relative "utils/string_transformations"
7
+ require_relative "sigil"
7
8
 
8
9
  module Mortymer
9
10
  # Include this module in your classes to register
10
11
  # and configure your classes as API endpoints.
11
12
  module ApiMetadata
12
13
  def self.included(base)
14
+ base.include(Sigil)
13
15
  base.extend(ClassMethods)
14
16
  end
15
17
 
@@ -84,12 +86,22 @@ module Mortymer
84
86
  rails_wrap_method_with_no_params_call(method_name, input_class, handlers)
85
87
  end
86
88
 
87
- def rails_wrap_method_with_no_params_call(method_name, input_class, handlers)
89
+ def rails_wrap_method_with_no_params_call(method_name, _input_class, handlers)
88
90
  original_method = instance_method(method_name)
89
91
  define_method(method_name) do
90
- input = input_class.structify(params.to_unsafe_h.to_h.deep_transform_keys(&:to_sym))
92
+ # Delegate input handling and checking to Sigil. It will coerce and
93
+ # validate contracts and structs
94
+ input = params.to_unsafe_h.to_h.deep_transform_keys(&:to_sym)
91
95
  output = original_method.bind_call(self, input)
92
- render json: output.to_h, status: :ok
96
+ # Output might not be validated, so if it is a hash, we will simple
97
+ # pass it through, otherwise we will call a to_h method
98
+ if output.respond_to?(:to_h)
99
+ render json: output.to_h, status: :ok
100
+ elsif output.respond_to?(:to_json)
101
+ render json: output.to_json, status: :ok
102
+ else
103
+ render json: output, status: :ok
104
+ end
93
105
  rescue StandardError => e
94
106
  handler = handlers.find { |h| e.is_a?(h[:exception]) }
95
107
  raise unless handler
@@ -105,6 +117,7 @@ module Mortymer
105
117
  end
106
118
 
107
119
  def register_endpoint(http_method, input_class, output_class, path, security)
120
+ sign input_class, returns: output_class
108
121
  @__endpoint_signature__ =
109
122
  {
110
123
  http_method: http_method,
@@ -19,7 +19,7 @@ module Mortymer
19
19
  # Global configuration for Mortymer
20
20
  class Configuration
21
21
  attr_accessor :container, :serve_swagger, :swagger_title, :swagger_path, :swagger_root, :api_version,
22
- :api_description, :security_schemes, :api_prefix
22
+ :api_description, :security_schemes, :api_prefix, :openapi_servers
23
23
 
24
24
  def initialize
25
25
  @container = Mortymer::Container.new
@@ -31,6 +31,7 @@ module Mortymer
31
31
  @api_version = "v1"
32
32
  @security_schemes = {}
33
33
  @api_prefix = "/api/v1"
34
+ @openapi_servers = []
34
35
  end
35
36
  end
36
37
  end
@@ -16,7 +16,15 @@ module Mortymer
16
16
  end
17
17
 
18
18
  def self.structify(params)
19
- call(params)
19
+ if params.instance_of?(self.class)
20
+ params
21
+ else
22
+ call(params)
23
+ end
24
+ end
25
+
26
+ def [](key)
27
+ @attributes[key.to_sym]
20
28
  end
21
29
  end
22
30
  end
@@ -10,18 +10,20 @@ module Mortymer
10
10
  include Utils::StringTransformations
11
11
 
12
12
  def initialize(prefix: "", title: "Rick on Rails API", version: "v1", description: "", registry: [], # rubocop:disable Metrics/ParameterLists
13
- security_schemes: {})
13
+ security_schemes: {}, openapi_servers: [])
14
14
  @prefix = prefix
15
15
  @title = title
16
16
  @version = version
17
17
  @description = description
18
18
  @endpoints_registry = registry
19
19
  @security_schemes = security_schemes
20
+ @openapi_servers = openapi_servers
20
21
  end
21
22
 
22
23
  def generate
23
24
  {
24
25
  openapi: "3.0.1",
26
+ servers: @openapi_servers,
25
27
  info: { title: @title, version: @version, description: @description },
26
28
  paths: generate_paths,
27
29
  components: {
@@ -28,7 +28,8 @@ module Mortymer
28
28
  version: Mortymer.config.api_version,
29
29
  description: Mortymer.config.api_description,
30
30
  security_schemes: Mortymer.config.security_schemes,
31
- prefix: Mortymer.config.api_prefix
31
+ prefix: Mortymer.config.api_prefix,
32
+ openapi_servers: Mortymer.config.openapi_servers
32
33
  )
33
34
 
34
35
  # Save OpenAPI spec to public directory
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require_relative "types"
4
+
3
5
  module Mortymer
4
6
  # Sigil provides symbolic type checking for input and outputs
5
7
  # of method calls using dry-types
@@ -19,8 +21,9 @@ module Mortymer
19
21
 
20
22
  # Hook called when a method is defined
21
23
  def method_added(method_name)
22
- return super if @pending_type_signature.nil?
23
- return super if @processing_type_check
24
+ super
25
+ return if @pending_type_signature.nil?
26
+ return if @processing_type_check
24
27
 
25
28
  signature = @pending_type_signature
26
29
  @pending_type_signature = nil
@@ -79,9 +82,7 @@ module Mortymer
79
82
  end
80
83
 
81
84
  @processing_type_check = false
82
-
83
85
  # Call super to maintain compatibility with other method hooks
84
- super
85
86
  end
86
87
  end
87
88
 
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Mortymer
4
- VERSION = "0.0.11"
4
+ VERSION = "0.0.12"
5
5
  end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mortymer
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.11
4
+ version: 0.0.12
5
5
  platform: ruby
6
6
  authors:
7
7
  - Adrian Gonzalez
8
8
  bindir: exe
9
9
  cert_chain: []
10
- date: 2025-03-31 00:00:00.000000000 Z
10
+ date: 2025-04-05 00:00:00.000000000 Z
11
11
  dependencies:
12
12
  - !ruby/object:Gem::Dependency
13
13
  name: dry-struct
@@ -95,6 +95,7 @@ files:
95
95
  - docs/guide/models.md
96
96
  - docs/guide/mortymer-dependency-injection.md
97
97
  - docs/guide/quick-start.md
98
+ - docs/guide/type-system.md
98
99
  - docs/index.md
99
100
  - lib/mortymer.rb
100
101
  - lib/mortymer/api_metadata.rb