diff --git a/lib/typelizer/dsl.rb b/lib/typelizer/dsl.rb index dda9742..ff0ce67 100644 --- a/lib/typelizer/dsl.rb +++ b/lib/typelizer/dsl.rb @@ -4,12 +4,12 @@ module DSL # typelize attribute_name: ["string", "Date", optional: true, nullable: true, multi: true] def self.included(base) - Typelizer.base_classes << base.to_s + Typelizer.base_classes << base.to_s if base.name base.extend(ClassMethods) end def self.extended(base) - Typelizer.base_classes << base.to_s + Typelizer.base_classes << base.to_s if base.name base.extend(ClassMethods) end diff --git a/lib/typelizer/generator.rb b/lib/typelizer/generator.rb index 2cbb6aa..f2ebde5 100644 --- a/lib/typelizer/generator.rb +++ b/lib/typelizer/generator.rb @@ -34,7 +34,7 @@ def target_serializers end (base_classes + base_classes.flat_map(&:descendants)).uniq - .reject { |serializer| Typelizer.reject_class.call(serializer: serializer) || serializer.name.nil? } + .reject { |serializer| Typelizer.reject_class.call(serializer: serializer) } .sort_by(&:name) end diff --git a/lib/typelizer/inline_type.rb b/lib/typelizer/inline_type.rb deleted file mode 100644 index 5f5f3f0..0000000 --- a/lib/typelizer/inline_type.rb +++ /dev/null @@ -1,22 +0,0 @@ -module Typelizer - # InlineType is mainly used with Alba plugin to represent inline associations. - # `name `method` is the same interface as `Interface` class. - class InlineType - TEMPLATE = <<~ERB.strip - { - <%- properties.each do |property| %> - <%= property %>; - <% end %> - } - ERB - def initialize(serializer:, config:) - @serializer = serializer - @config = config - end - - def name - properties = SerializerPlugins::Alba.new(serializer: @serializer, config: @config).properties - ERB.new(TEMPLATE, trim_mode: "-").result_with_hash(properties: properties) - end - end -end diff --git a/lib/typelizer/interface.rb b/lib/typelizer/interface.rb index c0f7625..e67ec3c 100644 --- a/lib/typelizer/interface.rb +++ b/lib/typelizer/interface.rb @@ -11,8 +11,16 @@ def initialize(serializer:) @serializer_plugin = config.serializer_plugin.new(serializer: serializer, config: config) end + def inline? + !serializer.is_a?(Class) || serializer.name.nil? + end + def name - config.serializer_name_mapper.call(serializer).tr_s(":", "") + if inline? + render_template("inline_type.ts.erb", properties: properties).strip + else + config.serializer_name_mapper.call(serializer).tr_s(":", "") + end end def filename @@ -51,10 +59,9 @@ def imports .partition { |type| type.is_a?(Interface) } serializer_types = association_serializers - .filter_map { |interface| interface.name if interface.name != name } + .filter_map { |interface| interface.name if interface.name != name && !interface.inline? } custom_type_imports = attribute_types - .reject { |type| type.is_a?(InlineType) } .flat_map { |type| extract_typescript_types(type.to_s) } .uniq .reject { |type| global_type?(type) } @@ -98,5 +105,10 @@ def model_class def model_plugin @model_plugin ||= config.model_plugin.new(model_class: model_class, config: config) end + + def render_template(template, **context) + ERB.new(File.read(File.join(File.dirname(__FILE__), "templates/#{template}")), trim_mode: "-") + .result_with_hash(context) + end end end diff --git a/lib/typelizer/serializer_plugins/alba.rb b/lib/typelizer/serializer_plugins/alba.rb index b61dd98..dfb4830 100644 --- a/lib/typelizer/serializer_plugins/alba.rb +++ b/lib/typelizer/serializer_plugins/alba.rb @@ -1,5 +1,4 @@ require_relative "base" -require_relative "../inline_type" module Typelizer module SerializerPlugins @@ -75,10 +74,9 @@ def build_property(name, attr, **options) ) when ::Alba::Association resource = attr.instance_variable_get(:@resource) - type = (resource.is_a?(Class) && !resource.name.nil?) ? Interface.new(serializer: resource) : InlineType.new(serializer: resource, config: {}) Property.new( name: name, - type: type, + type: Interface.new(serializer: resource), optional: false, nullable: false, multi: false, # we override this in typelize_method_transform diff --git a/lib/typelizer/templates/inline_type.ts.erb b/lib/typelizer/templates/inline_type.ts.erb new file mode 100644 index 0000000..3930f05 --- /dev/null +++ b/lib/typelizer/templates/inline_type.ts.erb @@ -0,0 +1,5 @@ +{ +<%- properties.each do |property| -%> +<%= property.to_s.strip.gsub(/^/, ' ') %>; +<%- end -%> +} diff --git a/lib/typelizer/templates/interface.ts.erb b/lib/typelizer/templates/interface.ts.erb index 6546178..705fc61 100644 --- a/lib/typelizer/templates/interface.ts.erb +++ b/lib/typelizer/templates/interface.ts.erb @@ -5,20 +5,20 @@ import type {<%= interface.imports.join(", ") %>} from '<%= interface.config.typ <%- if interface.root_key -%> type <%= interface.name %>Data = { <%- interface.properties.each do |property| -%> - <%= property %>; +<%= property.to_s.strip.gsub(/^/, ' ') %>; <%- end -%> } type <%= interface.name %> = { <%= interface.root_key %>: <%= interface.name %>Data; <%- interface.meta_fields&.each do |property| -%> - <%= property %>; +<%= property.to_s.strip.gsub(/^/, ' ') %>; <%- end -%> } <%- else -%> type <%= interface.name %> = { <%- interface.properties.each do |property| -%> - <%= property %>; +<%= property.to_s.strip.gsub(/^/, ' ') %>; <%- end -%> } <%- end -%> diff --git a/spec/__snapshots__/AlbaInline.ts.snap b/spec/__snapshots__/AlbaInline.ts.snap new file mode 100644 index 0000000..d0a6033 --- /dev/null +++ b/spec/__snapshots__/AlbaInline.ts.snap @@ -0,0 +1,27 @@ +// Typelizer digest 31c711d30b829018bdc69e3e09ca8e72 +// +// DO NOT MODIFY: This file was automatically generated by Typelizer. + +type AlbaInline = { + id: number; + username: string; + active: boolean; + untyped_posts: Array<{ + id: unknown; + title: unknown; + }>; + posts: Array<{ + id: number; + title: string; + }>; + deep_posts: Array<{ + id: number; + title: string | null; + user: { + id: number; + username: string; + }; + }>; +} + +export default AlbaInline; diff --git a/spec/__snapshots__/index.ts.snap b/spec/__snapshots__/index.ts.snap index e785483..648713e 100644 --- a/spec/__snapshots__/index.ts.snap +++ b/spec/__snapshots__/index.ts.snap @@ -1,6 +1,7 @@ -// Typelizer digest 3c3bed842a60e703fd96dab39cdc1cb5 +// Typelizer digest 57b8f7cafc55a420da0bed2b12cadf83 // // DO NOT MODIFY: This file was automatically generated by Typelizer. +export type { default as AlbaInline } from './AlbaInline' export type { default as AlbaMetaNil } from './AlbaMetaNil' export type { default as AlbaMeta } from './AlbaMeta' export type { default as AlbaPost } from './AlbaPost' diff --git a/spec/app/app/serializers/alba/base_serializer.rb b/spec/app/app/serializers/alba/base_serializer.rb index 2b18ff7..b47a0f7 100644 --- a/spec/app/app/serializers/alba/base_serializer.rb +++ b/spec/app/app/serializers/alba/base_serializer.rb @@ -1,7 +1,7 @@ module Alba class BaseSerializer include Alba::Resource - include Typelizer::DSL + helper Typelizer::DSL typelizer_config.null_strategy = :nullable_and_optional end diff --git a/spec/app/app/serializers/alba/inline_serializer.rb b/spec/app/app/serializers/alba/inline_serializer.rb new file mode 100644 index 0000000..9527685 --- /dev/null +++ b/spec/app/app/serializers/alba/inline_serializer.rb @@ -0,0 +1,26 @@ +module Alba + class InlineSerializer < BaseSerializer + typelize_from ::User + attributes :id, :username, :active + + has_many :untyped_posts do + attributes :id, :title + end + + has_many :posts do + typelize id: :number + + attributes :id, title: [String, true] + end + + has_many :deep_posts do + typelize_from ::Post + attributes :id, :title + + has_one :user do + typelize_from ::User + attributes :id, :username + end + end + end +end