typelizer 0.2.0 → 0.3.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 +4 -4
- data/CHANGELOG.md +43 -6
- data/README.md +1 -1
- data/lib/typelizer/interface.rb +5 -1
- data/lib/typelizer/property.rb +6 -1
- data/lib/typelizer/serializer_plugins/alba.rb +37 -7
- data/lib/typelizer/serializer_plugins/ams.rb +3 -1
- data/lib/typelizer/serializer_plugins/oj_serializers.rb +5 -1
- data/lib/typelizer/templates/interface.ts.erb +4 -1
- data/lib/typelizer/version.rb +1 -1
- data/lib/typelizer/writer.rb +1 -1
- metadata +3 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 391ff3345874135d72e3875c60aff109ebfd8ce98b0766e51dd1d2a8909e2af9
|
4
|
+
data.tar.gz: 1a3c12dad42402fc5485f3124660e2376db4f8dec7b36d016a8d48a33d568fa0
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6111652d2f134f20fa6450c1eccaf592a1bade20e0325b49b43a55628e9ac4f7eab1dfbfad09df0aa28893ae898571ccb486d92aa79f23cce682ab3d0c61b8d4
|
7
|
+
data.tar.gz: 1b73e070ce4dc50cc87d1a589a286afffcca8f42f596a6172e9b236e9911c72b45ea391d8e7b20ac8321eb83bb488f871c48d67e2a5ece6672530e0e897a6689
|
data/CHANGELOG.md
CHANGED
@@ -7,21 +7,57 @@ and this project adheres to [Semantic Versioning].
|
|
7
7
|
|
8
8
|
## [Unreleased]
|
9
9
|
|
10
|
+
## [0.3.0] - 2025-02-28
|
11
|
+
|
12
|
+
### Added
|
13
|
+
|
14
|
+
- Support transform keys. ([@patvice], [@skryukov])
|
15
|
+
|
16
|
+
Typelizer now respects `transform_keys`/`key_transform` configurations for all plugins.
|
17
|
+
|
18
|
+
- Support typing method def in Alba. ([@patvice])
|
19
|
+
|
20
|
+
The `typelize` helper now can be used before a method definition:
|
21
|
+
|
22
|
+
```ruby
|
23
|
+
class UserResource < ApplicationResource
|
24
|
+
attributes :id, :name, :email, :chars_in_name
|
25
|
+
|
26
|
+
typelize :number
|
27
|
+
def chars_in_name(obj)
|
28
|
+
obj.name.chars.count
|
29
|
+
end
|
30
|
+
end
|
31
|
+
```
|
32
|
+
|
33
|
+
- Support for deprecated attributes. ([@Envek])
|
34
|
+
|
35
|
+
They will be marked as deprecated using JSDoc [`@deprecated` tag](https://jsdoc.app/tags-deprecated) in TypeScript interface comments.
|
36
|
+
|
37
|
+
In ActiveModel::Serializer attributes `deprecated` option is recognized.
|
38
|
+
|
39
|
+
For other serializers, you can use `deprecated` option of `typelize` method.
|
40
|
+
|
41
|
+
### Fixed
|
42
|
+
|
43
|
+
- Ignore `nil` values on fingerprint calculation. ([@Envek])
|
44
|
+
|
10
45
|
## [0.2.0] - 2024-11-26
|
11
46
|
|
12
47
|
## Added
|
13
48
|
|
14
|
-
- Add support for enum attributes declared using `ActiveRecord::Enum` or explicitly in serializers ([@
|
15
|
-
- Add support for comments in generated TypeScript interfaces ([@
|
49
|
+
- Add support for enum attributes declared using `ActiveRecord::Enum` or explicitly in serializers ([@Envek])
|
50
|
+
- Add support for comments in generated TypeScript interfaces ([@Envek])
|
16
51
|
- Add TypeScript verbatim module syntax support through `verbatim_module_syntax` config option ([@patvice])
|
17
52
|
- Add `typelizer:generate:refresh` command to clean output directory and regenerate all interfaces ([@patvice])
|
18
53
|
- Allow disabling Typelizer in Rails development with `DISABLE_TYPELIZER` environment variable to `true` ([@okuramasafumi])
|
54
|
+
- Allow to get interfaces without generating TypeScript files ([@Envek])
|
19
55
|
|
20
|
-
##
|
56
|
+
## Fixed
|
21
57
|
|
22
58
|
- Do not override `Typelizer.dirs` in the railtie initializer ([@patvice])
|
23
59
|
- Do not raise on empty nested serializers ([@skryukov])
|
24
|
-
- Attribute options merging in inherited serializers ([@
|
60
|
+
- Attribute options merging in inherited serializers ([@Envek])
|
25
61
|
- Allow recursive type definition ([@okuramasafumi])
|
26
62
|
|
27
63
|
## [0.1.5] - 2024-10-07
|
@@ -75,12 +111,13 @@ and this project adheres to [Semantic Versioning].
|
|
75
111
|
- Initial release ([@skryukov])
|
76
112
|
|
77
113
|
[@davidrunger]: https://github.com/davidrunger
|
78
|
-
[@
|
114
|
+
[@Envek]: https://github.com/Envek
|
79
115
|
[@okuramasafumi]: https://github.com/okuramasafumi
|
80
116
|
[@patvice]: https://github.com/patvice
|
81
117
|
[@skryukov]: https://github.com/skryukov
|
82
118
|
|
83
|
-
[Unreleased]: https://github.com/skryukov/typelizer/compare/v0.
|
119
|
+
[Unreleased]: https://github.com/skryukov/typelizer/compare/v0.3.0...HEAD
|
120
|
+
[0.3.0]: https://github.com/skryukov/typelizer/compare/v0.2.0...v0.3.0
|
84
121
|
[0.2.0]: https://github.com/skryukov/typelizer/compare/v0.1.5...v0.2.0
|
85
122
|
[0.1.5]: https://github.com/skryukov/typelizer/compare/v0.1.4...v0.1.5
|
86
123
|
[0.1.4]: https://github.com/skryukov/typelizer/compare/v0.1.3...v0.1.4
|
data/README.md
CHANGED
@@ -105,7 +105,7 @@ end
|
|
105
105
|
You can also specify more complex type definitions using a lower-level API:
|
106
106
|
|
107
107
|
```ruby
|
108
|
-
typelize attribute_name: ["string", "Date", optional: true, nullable: true, multi: true, enum: %w[foo bar], comment: "Attribute description"]
|
108
|
+
typelize attribute_name: ["string", "Date", optional: true, nullable: true, multi: true, enum: %w[foo bar], comment: "Attribute description", deprecated: "Use `another_attribute` instead"]
|
109
109
|
```
|
110
110
|
|
111
111
|
### TypeScript Integration
|
data/lib/typelizer/interface.rb
CHANGED
@@ -73,6 +73,10 @@ module Typelizer
|
|
73
73
|
"<#{self.class.name} #{name} properties=#{properties.inspect}>"
|
74
74
|
end
|
75
75
|
|
76
|
+
def fingerprint
|
77
|
+
"<#{self.class.name} #{name} properties=[#{properties.map(&:fingerprint).join(", ")}]>"
|
78
|
+
end
|
79
|
+
|
76
80
|
private
|
77
81
|
|
78
82
|
def self_type_name
|
@@ -90,7 +94,7 @@ module Typelizer
|
|
90
94
|
def infer_types(props, hash_name = :_typelizer_attributes)
|
91
95
|
props.map do |prop|
|
92
96
|
if serializer.respond_to?(hash_name)
|
93
|
-
dsl_type = serializer.public_send(hash_name)[prop.
|
97
|
+
dsl_type = serializer.public_send(hash_name)[prop.column_name.to_sym]
|
94
98
|
if dsl_type&.any?
|
95
99
|
next Property.new(prop.to_h.merge(dsl_type)).tap do |property|
|
96
100
|
property.comment ||= model_plugin.comment_for(property) if config.comments && property.comment != false
|
data/lib/typelizer/property.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
module Typelizer
|
2
2
|
Property = Struct.new(
|
3
3
|
:name, :type, :optional, :nullable,
|
4
|
-
:multi, :column_name, :comment, :enum,
|
4
|
+
:multi, :column_name, :comment, :enum, :deprecated,
|
5
5
|
keyword_init: true
|
6
6
|
) do
|
7
7
|
def inspect
|
@@ -17,6 +17,11 @@ module Typelizer
|
|
17
17
|
"#{name}#{"?" if optional}: #{type_str}"
|
18
18
|
end
|
19
19
|
|
20
|
+
def fingerprint
|
21
|
+
props = to_h.merge(type: type_name).reject { |_, v| v.nil? }.map { |k, v| "#{k}=#{v.inspect}" }.join(" ")
|
22
|
+
"<#{self.class.name} #{props}>"
|
23
|
+
end
|
24
|
+
|
20
25
|
private
|
21
26
|
|
22
27
|
def type_name
|
@@ -22,19 +22,31 @@ module Typelizer
|
|
22
22
|
:association, :one, :has_one,
|
23
23
|
:many, :has_many,
|
24
24
|
:attributes, :attribute,
|
25
|
+
:method_added,
|
25
26
|
:nested_attribute, :nested,
|
26
27
|
:meta
|
27
28
|
]
|
28
29
|
end
|
29
30
|
|
30
31
|
def typelize_method_transform(method:, name:, binding:, type:, attrs:)
|
31
|
-
|
32
|
+
if method == :method_added && binding.local_variable_defined?(:method_name)
|
33
|
+
name = binding.local_variable_get(:method_name)
|
34
|
+
end
|
35
|
+
|
36
|
+
if [:many, :has_many].include?(method)
|
37
|
+
return {name => [type, attrs.merge(multi: true)]}
|
38
|
+
end
|
32
39
|
|
33
40
|
super
|
34
41
|
end
|
35
42
|
|
36
43
|
def root_key
|
37
|
-
serializer.new({}).send(:_key)
|
44
|
+
root = serializer.new({}).send(:_key)
|
45
|
+
if !root.nil? && has_transform_key?(serializer) && should_transform_root_key?(serializer)
|
46
|
+
fetch_key(serializer, root)
|
47
|
+
else
|
48
|
+
root
|
49
|
+
end
|
38
50
|
end
|
39
51
|
|
40
52
|
def meta_fields
|
@@ -51,6 +63,12 @@ module Typelizer
|
|
51
63
|
private
|
52
64
|
|
53
65
|
def build_property(name, attr, **options)
|
66
|
+
column_name = name
|
67
|
+
|
68
|
+
if has_transform_key?(serializer)
|
69
|
+
name = fetch_key(serializer, name)
|
70
|
+
end
|
71
|
+
|
54
72
|
case attr
|
55
73
|
when Symbol
|
56
74
|
Property.new(
|
@@ -59,7 +77,7 @@ module Typelizer
|
|
59
77
|
optional: false,
|
60
78
|
nullable: false,
|
61
79
|
multi: false,
|
62
|
-
column_name:
|
80
|
+
column_name: column_name,
|
63
81
|
**options
|
64
82
|
)
|
65
83
|
when Proc
|
@@ -69,7 +87,7 @@ module Typelizer
|
|
69
87
|
optional: false,
|
70
88
|
nullable: false,
|
71
89
|
multi: false,
|
72
|
-
column_name:
|
90
|
+
column_name: column_name,
|
73
91
|
**options
|
74
92
|
)
|
75
93
|
when ::Alba::Association
|
@@ -80,7 +98,7 @@ module Typelizer
|
|
80
98
|
optional: false,
|
81
99
|
nullable: false,
|
82
100
|
multi: false, # we override this in typelize_method_transform
|
83
|
-
column_name:
|
101
|
+
column_name: column_name,
|
84
102
|
**options
|
85
103
|
)
|
86
104
|
when ::Alba::TypedAttribute
|
@@ -91,7 +109,7 @@ module Typelizer
|
|
91
109
|
# not sure if that's a good default tbh
|
92
110
|
nullable: !alba_type.instance_variable_get(:@auto_convert),
|
93
111
|
multi: false,
|
94
|
-
column_name:
|
112
|
+
column_name: column_name,
|
95
113
|
**ts_mapper[alba_type.name.to_s],
|
96
114
|
**options
|
97
115
|
)
|
@@ -102,7 +120,7 @@ module Typelizer
|
|
102
120
|
optional: false,
|
103
121
|
nullable: false,
|
104
122
|
multi: false,
|
105
|
-
column_name:
|
123
|
+
column_name: column_name,
|
106
124
|
**options
|
107
125
|
)
|
108
126
|
when ::Alba::ConditionalAttribute
|
@@ -112,6 +130,18 @@ module Typelizer
|
|
112
130
|
end
|
113
131
|
end
|
114
132
|
|
133
|
+
def has_transform_key?(serializer)
|
134
|
+
serializer._transform_type != :none
|
135
|
+
end
|
136
|
+
|
137
|
+
def should_transform_root_key?(serializer)
|
138
|
+
serializer._transforming_root_key
|
139
|
+
end
|
140
|
+
|
141
|
+
def fetch_key(serializer, key)
|
142
|
+
::Alba.transform_key(key, transform_type: serializer._transform_type)
|
143
|
+
end
|
144
|
+
|
115
145
|
private
|
116
146
|
|
117
147
|
def ts_mapper
|
@@ -19,11 +19,13 @@ module Typelizer
|
|
19
19
|
def properties
|
20
20
|
serializer._attributes_data.merge(serializer._reflections).flat_map do |key, association|
|
21
21
|
type = association.options[:serializer] ? Interface.new(serializer: association.options[:serializer]) : nil
|
22
|
+
adapter = ActiveModelSerializers::Adapter.configured_adapter
|
22
23
|
Property.new(
|
23
|
-
name: key.to_s,
|
24
|
+
name: adapter.transform_key_casing!(key.to_s, association.options),
|
24
25
|
type: type,
|
25
26
|
optional: association.options.key?(:if) || association.options.key?(:unless),
|
26
27
|
multi: association.respond_to?(:collection?) && association.collection?,
|
28
|
+
deprecated: (association.options[:deprecated] if association.options.key?(:deprecated)),
|
27
29
|
column_name: association.name.to_s
|
28
30
|
)
|
29
31
|
end
|
@@ -11,7 +11,11 @@ module Typelizer
|
|
11
11
|
end
|
12
12
|
|
13
13
|
def properties
|
14
|
-
serializer.
|
14
|
+
transform_keys = serializer.try(:_transform_keys)
|
15
|
+
attributes = serializer._attributes
|
16
|
+
attributes = attributes.transform_keys(&transform_keys) if transform_keys
|
17
|
+
|
18
|
+
attributes
|
15
19
|
.flat_map do |key, options|
|
16
20
|
if options[:association] == :flat
|
17
21
|
Interface.new(serializer: options.fetch(:serializer)).properties
|
@@ -18,7 +18,10 @@ type <%= interface.name %> = {
|
|
18
18
|
<%- else -%>
|
19
19
|
type <%= interface.name %> = {
|
20
20
|
<%- interface.properties.each do |property| -%>
|
21
|
-
|
21
|
+
<%- comment = "" -%>
|
22
|
+
<%- comment += property.comment.to_s if interface.config.comments -%>
|
23
|
+
<%- comment += "\n@deprecated #{property.deprecated.is_a?(String) ? property.deprecated : ''}" if property.deprecated -%>
|
24
|
+
<%= indent("/** #{comment.strip.split("\n").map(&:strip).join("\n * ")} */\n") unless comment.empty? -%>
|
22
25
|
<%= indent(property) %>;
|
23
26
|
<%- end -%>
|
24
27
|
}
|
data/lib/typelizer/version.rb
CHANGED
data/lib/typelizer/writer.rb
CHANGED
@@ -32,7 +32,7 @@ module Typelizer
|
|
32
32
|
end
|
33
33
|
|
34
34
|
def write_interface(interface)
|
35
|
-
write_file("#{interface.filename}.ts", interface.
|
35
|
+
write_file("#{interface.filename}.ts", interface.fingerprint) do
|
36
36
|
render_template("interface.ts.erb", interface: interface)
|
37
37
|
end
|
38
38
|
end
|
metadata
CHANGED
@@ -1,14 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: typelizer
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Svyatoslav Kryukov
|
8
|
-
autorequire:
|
9
8
|
bindir: bin
|
10
9
|
cert_chain: []
|
11
|
-
date:
|
10
|
+
date: 2025-02-28 00:00:00.000000000 Z
|
12
11
|
dependencies:
|
13
12
|
- !ruby/object:Gem::Dependency
|
14
13
|
name: railties
|
@@ -67,7 +66,6 @@ metadata:
|
|
67
66
|
homepage_uri: https://github.com/skryukov/typelizer
|
68
67
|
source_code_uri: https://github.com/skryukov/typelizer
|
69
68
|
rubygems_mfa_required: 'true'
|
70
|
-
post_install_message:
|
71
69
|
rdoc_options: []
|
72
70
|
require_paths:
|
73
71
|
- lib
|
@@ -82,8 +80,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
82
80
|
- !ruby/object:Gem::Version
|
83
81
|
version: '0'
|
84
82
|
requirements: []
|
85
|
-
rubygems_version: 3.
|
86
|
-
signing_key:
|
83
|
+
rubygems_version: 3.6.2
|
87
84
|
specification_version: 4
|
88
85
|
summary: A TypeScript type generator for Ruby serializers.
|
89
86
|
test_files: []
|