typelizer 0.1.5 → 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 +59 -2
- data/README.md +47 -4
- data/lib/tasks/generate.rake +15 -2
- data/lib/typelizer/config.rb +5 -2
- data/lib/typelizer/dsl.rb +4 -2
- data/lib/typelizer/generator.rb +9 -5
- data/lib/typelizer/interface.rb +16 -3
- data/lib/typelizer/model_plugins/active_record.rb +19 -3
- data/lib/typelizer/model_plugins/poro.rb +8 -0
- data/lib/typelizer/property.rb +8 -1
- data/lib/typelizer/railtie.rb +6 -4
- 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/index.ts.erb +4 -0
- data/lib/typelizer/templates/interface.ts.erb +8 -0
- data/lib/typelizer/version.rb +1 -1
- data/lib/typelizer/writer.rb +1 -1
- data/lib/typelizer.rb +3 -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,6 +7,59 @@ 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
|
+
|
45
|
+
## [0.2.0] - 2024-11-26
|
46
|
+
|
47
|
+
## Added
|
48
|
+
|
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])
|
51
|
+
- Add TypeScript verbatim module syntax support through `verbatim_module_syntax` config option ([@patvice])
|
52
|
+
- Add `typelizer:generate:refresh` command to clean output directory and regenerate all interfaces ([@patvice])
|
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])
|
55
|
+
|
56
|
+
## Fixed
|
57
|
+
|
58
|
+
- Do not override `Typelizer.dirs` in the railtie initializer ([@patvice])
|
59
|
+
- Do not raise on empty nested serializers ([@skryukov])
|
60
|
+
- Attribute options merging in inherited serializers ([@Envek])
|
61
|
+
- Allow recursive type definition ([@okuramasafumi])
|
62
|
+
|
10
63
|
## [0.1.5] - 2024-10-07
|
11
64
|
|
12
65
|
## Fixed
|
@@ -58,10 +111,14 @@ and this project adheres to [Semantic Versioning].
|
|
58
111
|
- Initial release ([@skryukov])
|
59
112
|
|
60
113
|
[@davidrunger]: https://github.com/davidrunger
|
61
|
-
[@
|
114
|
+
[@Envek]: https://github.com/Envek
|
115
|
+
[@okuramasafumi]: https://github.com/okuramasafumi
|
116
|
+
[@patvice]: https://github.com/patvice
|
62
117
|
[@skryukov]: https://github.com/skryukov
|
63
118
|
|
64
|
-
[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
|
121
|
+
[0.2.0]: https://github.com/skryukov/typelizer/compare/v0.1.5...v0.2.0
|
65
122
|
[0.1.5]: https://github.com/skryukov/typelizer/compare/v0.1.4...v0.1.5
|
66
123
|
[0.1.4]: https://github.com/skryukov/typelizer/compare/v0.1.3...v0.1.4
|
67
124
|
[0.1.3]: https://github.com/skryukov/typelizer/compare/v0.1.2...v0.1.3
|
data/README.md
CHANGED
@@ -14,6 +14,7 @@ Typelizer is a Ruby gem that automatically generates TypeScript interfaces from
|
|
14
14
|
- [TypeScript Integration](#typescript-integration)
|
15
15
|
- [Manual Generation](#manual-generation)
|
16
16
|
- [Automatic Generation in Development](#automatic-generation-in-development)
|
17
|
+
- [Disabling Typelizer](#disabling-typelizer)
|
17
18
|
- [Configuration](#configuration)
|
18
19
|
- [Global Configuration](#global-configuration)
|
19
20
|
- [Config Options](#config-options)
|
@@ -79,9 +80,34 @@ class PostResource < ApplicationResource
|
|
79
80
|
attribute :author_name do |post|
|
80
81
|
post.author.name
|
81
82
|
end
|
83
|
+
|
84
|
+
typelize :string, nullable: true, comment: "Author's avatar URL"
|
85
|
+
attribute :avatar do
|
86
|
+
"https://example.com/avatar.png" if active?
|
87
|
+
end
|
82
88
|
end
|
83
89
|
```
|
84
90
|
|
91
|
+
`typelize` can be used with a Hash to specify multiple types at once.
|
92
|
+
|
93
|
+
```ruby
|
94
|
+
class PostResource < ApplicationResource
|
95
|
+
attributes :id, :title, :body, :published_at
|
96
|
+
|
97
|
+
attribute :author_name do |post|
|
98
|
+
post.author.name
|
99
|
+
end
|
100
|
+
|
101
|
+
typelize author_name: :string, published_at: :string
|
102
|
+
end
|
103
|
+
```
|
104
|
+
|
105
|
+
You can also specify more complex type definitions using a lower-level API:
|
106
|
+
|
107
|
+
```ruby
|
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
|
+
```
|
110
|
+
|
85
111
|
### TypeScript Integration
|
86
112
|
|
87
113
|
Typelizer generates TypeScript interfaces in the specified output directory:
|
@@ -91,6 +117,7 @@ Typelizer generates TypeScript interfaces in the specified output directory:
|
|
91
117
|
export interface Post {
|
92
118
|
id: number;
|
93
119
|
title: string;
|
120
|
+
category?: "news" | "article" | "blog" | null;
|
94
121
|
body: string;
|
95
122
|
published_at: string | null;
|
96
123
|
author_name: string;
|
@@ -156,11 +183,15 @@ See the [Configuration](#configuration) section for more options.
|
|
156
183
|
|
157
184
|
### Manual Generation
|
158
185
|
|
159
|
-
To manually generate TypeScript interfaces:
|
186
|
+
To manually generate TypeScript interfaces use one of the following commands:
|
160
187
|
|
161
|
-
```
|
162
|
-
|
163
|
-
|
188
|
+
```bash
|
189
|
+
# Generate new interfaces
|
190
|
+
rails typelizer:generate
|
191
|
+
|
192
|
+
# Clean output directory and regenerate all interfaces
|
193
|
+
rails typelizer:generate:refresh
|
194
|
+
````
|
164
195
|
|
165
196
|
### Automatic Generation in Development
|
166
197
|
|
@@ -170,6 +201,10 @@ When [Listen](https://github.com/guard/listen) is installed, Typelizer automatic
|
|
170
201
|
Typelizer.listen = false
|
171
202
|
```
|
172
203
|
|
204
|
+
### Disabling Typelizer
|
205
|
+
|
206
|
+
Sometimes we want to use Typelizer only with manual generation. To disable Typelizer during development, we can set `DISABLE_TYPELIZER` environment variable to `true`. This doesn't affect manual generation.
|
207
|
+
|
173
208
|
## Configuration
|
174
209
|
|
175
210
|
### Global Configuration
|
@@ -227,6 +262,14 @@ Typelizer.configure do |config|
|
|
227
262
|
# List of type names that should be considered global in TypeScript
|
228
263
|
# (i.e. not prefixed with the import path)
|
229
264
|
config.types_global << %w[Array Date Record File FileList]
|
265
|
+
|
266
|
+
# Support TypeScript's Verbatim module syntax option (default: false)
|
267
|
+
# Will change imports and exports of types from default to support this syntax option
|
268
|
+
config.verbatim_module_syntax = false
|
269
|
+
|
270
|
+
# Support comments in generated TypeScript interfaces (default: false)
|
271
|
+
# Will add comments to the generated interfaces
|
272
|
+
config.comments = false
|
230
273
|
end
|
231
274
|
```
|
232
275
|
|
data/lib/tasks/generate.rake
CHANGED
@@ -1,14 +1,27 @@
|
|
1
1
|
namespace :typelizer do
|
2
2
|
desc "Generate TypeScript interfaces from serializers"
|
3
3
|
task generate: :environment do
|
4
|
+
benchmark do
|
5
|
+
Typelizer::Generator.call
|
6
|
+
end
|
7
|
+
end
|
8
|
+
|
9
|
+
desc "Removes all files in output folder and refreshs all generate TypeScript interfaces from serializers"
|
10
|
+
task "generate:refresh": :environment do
|
11
|
+
benchmark do
|
12
|
+
Typelizer::Generator.call(force: true)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def benchmark(&block)
|
4
17
|
require "benchmark"
|
5
18
|
|
6
|
-
ENV["
|
19
|
+
ENV["DISABLE_TYPELIZER"] = "false"
|
7
20
|
|
8
21
|
puts "Generating TypeScript interfaces..."
|
9
22
|
serializers = []
|
10
23
|
time = Benchmark.realtime do
|
11
|
-
serializers =
|
24
|
+
serializers = block.call
|
12
25
|
end
|
13
26
|
|
14
27
|
puts "Finished in #{time} seconds"
|
data/lib/typelizer/config.rb
CHANGED
@@ -24,6 +24,8 @@ module Typelizer
|
|
24
24
|
:output_dir,
|
25
25
|
:types_import_path,
|
26
26
|
:types_global,
|
27
|
+
:verbatim_module_syntax,
|
28
|
+
:comments,
|
27
29
|
keyword_init: true
|
28
30
|
) do
|
29
31
|
class << self
|
@@ -45,13 +47,15 @@ module Typelizer
|
|
45
47
|
|
46
48
|
type_mapping: TYPE_MAPPING,
|
47
49
|
null_strategy: :nullable,
|
50
|
+
comments: false,
|
48
51
|
|
49
52
|
output_dir: js_root.join("types/serializers"),
|
50
53
|
|
51
54
|
types_import_path: "@/types",
|
52
55
|
types_global: %w[Array Date Record File FileList],
|
53
56
|
|
54
|
-
properties_transformer: nil
|
57
|
+
properties_transformer: nil,
|
58
|
+
verbatim_module_syntax: false
|
55
59
|
)
|
56
60
|
end
|
57
61
|
|
@@ -70,7 +74,6 @@ module Typelizer
|
|
70
74
|
|
71
75
|
def method_missing(method, *args, &block)
|
72
76
|
return Typelizer.send(method, *args, &block) if Typelizer.respond_to?(method)
|
73
|
-
|
74
77
|
instance.send(method, *args, &block)
|
75
78
|
end
|
76
79
|
end
|
data/lib/typelizer/dsl.rb
CHANGED
@@ -64,9 +64,11 @@ module Typelizer
|
|
64
64
|
|
65
65
|
unless respond_to?(attribute_name)
|
66
66
|
define_singleton_method(attribute_name) do
|
67
|
-
result = instance_variable_get(instance_variable)
|
67
|
+
result = instance_variable_get(instance_variable) || {}
|
68
68
|
if superclass.respond_to?(attribute_name)
|
69
|
-
result.merge(superclass.send(attribute_name))
|
69
|
+
result.merge(superclass.send(attribute_name)) do |key, currentdef, supervaldef|
|
70
|
+
supervaldef.merge(currentdef)
|
71
|
+
end
|
70
72
|
else
|
71
73
|
result
|
72
74
|
end
|
data/lib/typelizer/generator.rb
CHANGED
@@ -2,8 +2,8 @@
|
|
2
2
|
|
3
3
|
module Typelizer
|
4
4
|
class Generator
|
5
|
-
def self.call
|
6
|
-
new.call
|
5
|
+
def self.call(**args)
|
6
|
+
new.call(**args)
|
7
7
|
end
|
8
8
|
|
9
9
|
def initialize(config = Typelizer::Config)
|
@@ -16,14 +16,18 @@ module Typelizer
|
|
16
16
|
def call(force: false)
|
17
17
|
return unless Typelizer.enabled?
|
18
18
|
|
19
|
-
read_serializers
|
20
|
-
|
21
|
-
interfaces = target_serializers.map(&:typelizer_interface).reject(&:empty?)
|
22
19
|
writer.call(interfaces, force: force)
|
23
20
|
|
24
21
|
interfaces
|
25
22
|
end
|
26
23
|
|
24
|
+
def interfaces
|
25
|
+
@interfaces ||= begin
|
26
|
+
read_serializers
|
27
|
+
target_serializers.map(&:typelizer_interface).reject(&:empty?)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
27
31
|
private
|
28
32
|
|
29
33
|
def target_serializers
|
data/lib/typelizer/interface.rb
CHANGED
@@ -66,15 +66,23 @@ module Typelizer
|
|
66
66
|
.uniq
|
67
67
|
.reject { |type| global_type?(type) }
|
68
68
|
|
69
|
-
(custom_type_imports + serializer_types).uniq
|
69
|
+
(custom_type_imports + serializer_types).uniq - Array(self_type_name)
|
70
70
|
end
|
71
71
|
|
72
72
|
def inspect
|
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
|
|
82
|
+
def self_type_name
|
83
|
+
serializer.name.match(/(\w+::)?(\w+)(Serializer|Resource)/)[2]
|
84
|
+
end
|
85
|
+
|
78
86
|
def extract_typescript_types(type)
|
79
87
|
type.split(/[<>\[\],\s|]+/)
|
80
88
|
end
|
@@ -86,8 +94,13 @@ module Typelizer
|
|
86
94
|
def infer_types(props, hash_name = :_typelizer_attributes)
|
87
95
|
props.map do |prop|
|
88
96
|
if serializer.respond_to?(hash_name)
|
89
|
-
dsl_type = serializer.public_send(hash_name)[prop.
|
90
|
-
|
97
|
+
dsl_type = serializer.public_send(hash_name)[prop.column_name.to_sym]
|
98
|
+
if dsl_type&.any?
|
99
|
+
next Property.new(prop.to_h.merge(dsl_type)).tap do |property|
|
100
|
+
property.comment ||= model_plugin.comment_for(property) if config.comments && property.comment != false
|
101
|
+
property.enum ||= model_plugin.enum_for(property) if property.enum != false
|
102
|
+
end
|
103
|
+
end
|
91
104
|
end
|
92
105
|
|
93
106
|
model_plugin.infer_types(prop)
|
@@ -2,14 +2,14 @@ module Typelizer
|
|
2
2
|
module ModelPlugins
|
3
3
|
class ActiveRecord
|
4
4
|
def initialize(model_class:, config:)
|
5
|
-
@
|
5
|
+
@model_class = model_class
|
6
6
|
@config = config
|
7
7
|
end
|
8
8
|
|
9
|
-
attr_reader :
|
9
|
+
attr_reader :model_class, :config
|
10
10
|
|
11
11
|
def infer_types(prop)
|
12
|
-
column = columns_hash
|
12
|
+
column = model_class&.columns_hash&.dig(prop.column_name.to_s)
|
13
13
|
return prop unless column
|
14
14
|
|
15
15
|
prop.multi = !!column.try(:array)
|
@@ -26,9 +26,25 @@ module Typelizer
|
|
26
26
|
end
|
27
27
|
|
28
28
|
prop.type = @config.type_mapping[column.type]
|
29
|
+
prop.comment = comment_for(prop)
|
30
|
+
prop.enum = enum_for(prop)
|
31
|
+
prop.type = :string if prop.enum # Ignore underlying column type for enums
|
29
32
|
|
30
33
|
prop
|
31
34
|
end
|
35
|
+
|
36
|
+
def comment_for(prop)
|
37
|
+
column = model_class&.columns_hash&.dig(prop.column_name.to_s)
|
38
|
+
return nil unless column
|
39
|
+
|
40
|
+
prop.comment = column.comment
|
41
|
+
end
|
42
|
+
|
43
|
+
def enum_for(prop)
|
44
|
+
return unless model_class&.defined_enums&.key?(prop.column_name.to_s)
|
45
|
+
|
46
|
+
prop.enum = model_class.defined_enums[prop.column_name.to_s].keys
|
47
|
+
end
|
32
48
|
end
|
33
49
|
end
|
34
50
|
end
|
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,
|
4
|
+
:multi, :column_name, :comment, :enum, :deprecated,
|
5
5
|
keyword_init: true
|
6
6
|
) do
|
7
7
|
def inspect
|
@@ -17,9 +17,16 @@ 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
|
28
|
+
return enum.map { |v| v.to_s.inspect }.join(" | ") if enum
|
29
|
+
|
23
30
|
type.respond_to?(:name) ? type.name : type || "unknown"
|
24
31
|
end
|
25
32
|
end
|
data/lib/typelizer/railtie.rb
CHANGED
@@ -6,10 +6,12 @@ module Typelizer
|
|
6
6
|
|
7
7
|
initializer "typelizer.configure" do
|
8
8
|
Typelizer.configure do |c|
|
9
|
-
c.dirs
|
10
|
-
|
11
|
-
|
12
|
-
|
9
|
+
if c.dirs.empty?
|
10
|
+
c.dirs = [
|
11
|
+
Rails.root.join("app", "resources"),
|
12
|
+
Rails.root.join("app", "serializers")
|
13
|
+
]
|
14
|
+
end
|
13
15
|
end
|
14
16
|
end
|
15
17
|
|
@@ -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
|
@@ -1,3 +1,7 @@
|
|
1
1
|
<%- interfaces.each do |interface| -%>
|
2
|
+
<%- if interface.config.verbatim_module_syntax -%>
|
3
|
+
export type { <%= interface.name %> } from './<%= interface.filename %>'
|
4
|
+
<%- else -%>
|
2
5
|
export type { default as <%= interface.name %> } from './<%= interface.filename %>'
|
3
6
|
<%- end -%>
|
7
|
+
<%- end -%>
|
@@ -18,9 +18,17 @@ type <%= interface.name %> = {
|
|
18
18
|
<%- else -%>
|
19
19
|
type <%= interface.name %> = {
|
20
20
|
<%- interface.properties.each do |property| -%>
|
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? -%>
|
21
25
|
<%= indent(property) %>;
|
22
26
|
<%- end -%>
|
23
27
|
}
|
24
28
|
<%- end -%>
|
25
29
|
|
30
|
+
<%-if interface.config.verbatim_module_syntax -%>
|
31
|
+
export type { <%= interface.name %> };
|
32
|
+
<%- else -%>
|
26
33
|
export default <%= interface.name %>;
|
34
|
+
<%- end -%>
|
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
|
data/lib/typelizer.rb
CHANGED
@@ -26,7 +26,9 @@ require "logger"
|
|
26
26
|
module Typelizer
|
27
27
|
class << self
|
28
28
|
def enabled?
|
29
|
-
|
29
|
+
return false if ENV["DISABLE_TYPELIZER"] == "true" || ENV["DISABLE_TYPELIZER"] == "1"
|
30
|
+
|
31
|
+
ENV["RAILS_ENV"] == "development" || ENV["RACK_ENV"] == "development" || ENV["DISABLE_TYPELIZER"] == "false"
|
30
32
|
end
|
31
33
|
|
32
34
|
attr_accessor :dirs
|
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: []
|