Skip to content

Commit

Permalink
Introduce alternative approach to inline associations
Browse files Browse the repository at this point in the history
  • Loading branch information
skryukov committed Sep 22, 2024
1 parent dc70d5f commit 267c1ca
Show file tree
Hide file tree
Showing 11 changed files with 83 additions and 36 deletions.
4 changes: 2 additions & 2 deletions lib/typelizer/dsl.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
2 changes: 1 addition & 1 deletion lib/typelizer/generator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
22 changes: 0 additions & 22 deletions lib/typelizer/inline_type.rb

This file was deleted.

18 changes: 15 additions & 3 deletions lib/typelizer/interface.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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) }
Expand Down Expand Up @@ -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
4 changes: 1 addition & 3 deletions lib/typelizer/serializer_plugins/alba.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
require_relative "base"
require_relative "../inline_type"

module Typelizer
module SerializerPlugins
Expand Down Expand Up @@ -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
Expand Down
5 changes: 5 additions & 0 deletions lib/typelizer/templates/inline_type.ts.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
<%- properties.each do |property| -%>
<%= property.to_s.strip.gsub(/^/, ' ') %>;
<%- end -%>
}
6 changes: 3 additions & 3 deletions lib/typelizer/templates/interface.ts.erb
Original file line number Diff line number Diff line change
Expand Up @@ -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 -%>
Expand Down
27 changes: 27 additions & 0 deletions spec/__snapshots__/AlbaInline.ts.snap
Original file line number Diff line number Diff line change
@@ -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;
3 changes: 2 additions & 1 deletion spec/__snapshots__/index.ts.snap
Original file line number Diff line number Diff line change
@@ -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'
Expand Down
2 changes: 1 addition & 1 deletion spec/app/app/serializers/alba/base_serializer.rb
Original file line number Diff line number Diff line change
@@ -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
Expand Down
26 changes: 26 additions & 0 deletions spec/app/app/serializers/alba/inline_serializer.rb
Original file line number Diff line number Diff line change
@@ -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

0 comments on commit 267c1ca

Please sign in to comment.