mochitype 0.3.0 → 0.4.0

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: 7832035805b331f4ce0e845f3104c4f0356f24489c9c649374778fc6196f3618
4
- data.tar.gz: 4664df36000c2773999da7eec7b11889ab5e03eeed8836d92ee27494ee104672
3
+ metadata.gz: 128881600f5d6729560b0048753d2de5c99ff61e8477f10d6adac36ffff2a643
4
+ data.tar.gz: 369241d942dc83d7ff374b9febad50558dddf9e9459199118f8ab6d04c8864f9
5
5
  SHA512:
6
- metadata.gz: dcc0c4a00a8eb1f7c239d00e39dd839e664fda815ead297c13a444cda25b0ea2c8c6ef8181f3bf4ebc6eaa150555aa5a9ef290511db89717a30da9e587596092
7
- data.tar.gz: 118f4b24547826d9bfec06a0e49da2e7c9012c3495b70919ffda5fc867683565b69221d47b23cd3845bcfece8a3c8514ed4ed7666fdfec5bf2f97877e41d29e0
6
+ metadata.gz: f08cdcd021ebffa79e55e2c1ae6ad13b83832a458e554d650761f48902f0355e3218fca4f87f48be9914c03078e1036f8515430aef63b5bab7571e363ce85152
7
+ data.tar.gz: bf9c0dfc21fe2c250638037471f4a4a3e2acd95a74f1f423a319af909becbf293bfe34a0704831c08981dc5c8a5c27786b3a1af37fef10f4be5037cccc208311
data/README.md CHANGED
@@ -98,11 +98,14 @@ Now if you change UsersController#index to return something different, it'll upd
98
98
 
99
99
  ## Using Mochitype::View for Rendering
100
100
 
101
- The `Mochitype::View` module provides a simple way to make your `T::Struct` classes renderable in Rails controllers. When you include this module, your struct gains two methods:
101
+ The `Mochitype::View` module provides a simple way to make your `T::Struct` classes renderable in Rails controllers. When you include this module, your struct gains three methods:
102
102
 
103
- - `render_in(view_context)` - Serializes the struct to JSON
103
+ - `serialize` - Overrides T::Struct's default serialize to always include nil keys (instead of omitting them)
104
+ - `render_in(view_context)` - Serializes the struct to JSON using the above serialize method
104
105
  - `format` - Returns `:json` to indicate the response format
105
106
 
107
+ **Note:** Unlike Sorbet's default `T::Struct#serialize` which omits keys with nil values, `Mochitype::View#serialize` always includes all keys. This ensures consistent JSON structure that matches your generated Zod schemas.
108
+
106
109
  ### Basic Usage
107
110
 
108
111
  Include `Mochitype::View` in any `T::Struct` class:
@@ -200,7 +203,7 @@ This keeps your frontend types perfectly in sync with your backend responses!
200
203
 
201
204
  - Currently only works with T::Structs, T::Enum, and standard Ruby types like String, Integer, etc. If your struct has a field that's a custom class, it will be marked as `unknown`
202
205
  - Since we're using the Prism parser, it requires Ruby 3.3.5+
203
- - It does not de-dupe types across files. For example, if you have MyStruct and reference MyOtherStruct, both of those Typescript files will contain TS on MyOtherStruct.
206
+ - It does not de-dupe types across files. For example, if you have MyStruct and reference MyOtherStruct, both of those Typescript files will contain TS on MyOtherStruct
204
207
 
205
208
  ## Development
206
209
 
@@ -0,0 +1,34 @@
1
+ # typed: true
2
+ # frozen_string_literal: true
3
+
4
+ module Mochitype
5
+ # Recursively serializes T::Struct and T::Enum objects to hashes.
6
+ # Unlike Sorbet's default serialize, this always includes nil keys
7
+ # instead of omitting them, ensuring consistent JSON output for frontend types.
8
+ module RecursiveSerializer
9
+ extend T::Sig
10
+
11
+ sig { params(value: T.untyped).returns(T.untyped) }
12
+ def self.serialize_value(value)
13
+ case value
14
+ when T::Struct
15
+ serialize_struct(value)
16
+ when T::Enum
17
+ value.serialize
18
+ when Array
19
+ value.map { |v| serialize_value(v) }
20
+ when Hash
21
+ value.transform_values { |v| serialize_value(v) }
22
+ else
23
+ value
24
+ end
25
+ end
26
+
27
+ sig { params(obj: T::Struct).returns(T::Hash[String, T.untyped]) }
28
+ def self.serialize_struct(obj)
29
+ obj.class.props.keys.each_with_object({}) do |prop_name, h|
30
+ h[prop_name.to_s] = serialize_value(obj.public_send(prop_name))
31
+ end
32
+ end
33
+ end
34
+ end
@@ -1,3 +1,3 @@
1
1
  module Mochitype
2
- VERSION = '0.3.0'
2
+ VERSION = '0.4.0'
3
3
  end
@@ -5,6 +5,13 @@ module Mochitype
5
5
  module View
6
6
  extend T::Sig
7
7
 
8
+ # Overrides T::Struct#serialize to always include nil keys in the output.
9
+ # This ensures consistent JSON structure for frontend type safety with Zod schemas.
10
+ sig { returns(T::Hash[String, T.untyped]) }
11
+ def serialize
12
+ Mochitype::RecursiveSerializer.serialize_struct(self)
13
+ end
14
+
8
15
  sig { params(view_context: ActionView::Base).returns(String) }
9
16
  def render_in(view_context)
10
17
  serialize.to_json
data/lib/mochitype.rb CHANGED
@@ -13,6 +13,7 @@ require 'mochitype/convertible_class'
13
13
  require 'mochitype/type_converter'
14
14
  require 'mochitype/reflection_type_converter'
15
15
 
16
+ require 'mochitype/recursive_serializer'
16
17
  require 'mochitype/view'
17
18
  require 'mochitype/file_watcher'
18
19
  require 'mochitype/railtie' if defined?(Rails)
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mochitype
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Your Name
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2025-11-04 00:00:00.000000000 Z
11
+ date: 2025-12-16 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -123,6 +123,7 @@ files:
123
123
  - lib/mochitype/convertible_property.rb
124
124
  - lib/mochitype/file_watcher.rb
125
125
  - lib/mochitype/railtie.rb
126
+ - lib/mochitype/recursive_serializer.rb
126
127
  - lib/mochitype/reflection_type_converter.rb
127
128
  - lib/mochitype/ruby_type_utils.rb
128
129
  - lib/mochitype/type_converter.rb