Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ PATH
specs:
ar_sync (1.0.3)
activerecord
ar_serializer (= 1.0.0)
ar_serializer

GEM
remote: https://rubygems.org/
Expand All @@ -21,7 +21,7 @@ GEM
i18n (>= 0.7, < 2)
minitest (~> 5.1)
tzinfo (~> 1.1)
ar_serializer (1.0.0)
ar_serializer (1.1.0)
activerecord
top_n_loader
arel (9.0.0)
Expand All @@ -37,7 +37,7 @@ GEM
rake (12.3.2)
sqlite3 (1.3.13)
thread_safe (0.3.6)
top_n_loader (1.0.0)
top_n_loader (1.0.1)
activerecord
tzinfo (1.2.5)
thread_safe (~> 0.1)
Expand All @@ -53,4 +53,4 @@ DEPENDENCIES
sqlite3

BUNDLED WITH
1.16.1
2.1.2
2 changes: 1 addition & 1 deletion ar_sync.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ Gem::Specification.new do |spec|
spec.require_paths = ['lib']

spec.add_dependency 'activerecord'
spec.add_dependency 'ar_serializer', '1.0.0'
spec.add_dependency 'ar_serializer'
%w[rake pry sqlite3 activerecord-import].each do |gem_name|
spec.add_development_dependency gem_name
end
Expand Down
6 changes: 3 additions & 3 deletions lib/ar_sync/class_methods.rb
Original file line number Diff line number Diff line change
Expand Up @@ -64,14 +64,14 @@ def _sync_has_many(name, order: :asc, limit: nil, preload: nil, association: nil
raise "order not in [:asc, :desc] : #{order}" unless %i[asc desc].include? order
if data_block.nil? && preload.nil?
underscore_name = name.to_s.underscore.to_sym
preload = lambda do |records, _context, params|
preload = lambda do |records, _context, **params|
ArSerializer::Field.preload_association(
self, records, association || underscore_name,
order: (!limit && params && params[:order]) || order,
limit: [params && params[:limit]&.to_i, limit].compact.min
)
end
data_block = lambda do |preloaded, _context, params|
data_block = lambda do |preloaded, _context, **params|
records = preloaded ? preloaded[id] || [] : send(name)
next records unless limit || order == :asc
ArSync::CollectionWithOrder.new(
Expand All @@ -80,7 +80,7 @@ def _sync_has_many(name, order: :asc, limit: nil, preload: nil, association: nil
limit: [params && params[:limit]&.to_i, limit].compact.min
)
end
serializer_data_block = lambda do |preloaded, _context, _params|
serializer_data_block = lambda do |preloaded, _context, **_params|
preloaded ? preloaded[id] || [] : send(name)
end
params_type = { limit?: :int, order?: [{ :* => %w[asc desc] }, 'asc', 'desc'] }
Expand Down
4 changes: 2 additions & 2 deletions lib/ar_sync/instance_methods.rb
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,10 @@ def _sync_current_parents_info
def _serializer_field_value(name)
field = self.class._serializer_field_info name
preloadeds = field.preloaders.map do |preloader|
args = [[self], nil, {}]
args = [[self], nil]
preloader.call(*(preloader.arity < 0 ? args : args.take(preloader.arity)))
end
instance_exec(*preloadeds, nil, {}, &field.data_block)
instance_exec(*preloadeds, nil, &field.data_block)
end

def _sync_current_belongs_to_info
Expand Down
47 changes: 41 additions & 6 deletions lib/ar_sync/type_script.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,17 +10,14 @@ def self.generate_typed_files(api_class, dir:, comment: nil)
end

def self.generate_type_definition(api_class)
types = ArSerializer::TypeScript.related_serializer_types([api_class]).reject { |t| t.type == api_class }
[
ArSerializer::TypeScript.generate_type_definition(api_related_classes(api_class)),
types.map { |t| data_type_definition t },
types.map { |t| query_type_definition t },
request_type_definition(api_class)
].join "\n"
end

def self.api_related_classes(api_class)
classes = ArSerializer::TypeScript.related_serializer_types([api_class]).map(&:type)
classes - [api_class]
end

def self.request_type_definition(api_class)
type = ArSerializer::GraphQL::TypeClass.from api_class
definitions = []
Expand Down Expand Up @@ -98,4 +95,42 @@ def self.generate_hooks_script
}
CODE
end

def self.query_type_definition(type)
field_definitions = type.fields.map do |field|
association_type = field.type.association_type
if association_type
qname = "Type#{association_type.name}Query"
if field.args.empty?
"#{field.name}?: true | #{qname} | { attributes?: #{qname} }"
else
"#{field.name}?: true | #{qname} | { params: #{field.args_ts_type}; attributes?: #{qname} }"
end
else
"#{field.name}?: true"
end
end
field_definitions << "'*'?: true"
query_type_name = "Type#{type.name}Query"
base_query_type_name = "Type#{type.name}QueryBase"
<<~TYPE
export type #{query_type_name} = keyof (#{base_query_type_name}) | Readonly<(keyof (#{base_query_type_name}))[]> | #{base_query_type_name}
export interface #{base_query_type_name} {
#{field_definitions.map { |line| " #{line}" }.join("\n")}
}
TYPE
end

def self.data_type_definition(type)
field_definitions = []
type.fields.each do |field|
field_definitions << "#{field.name}: #{field.type.ts_type}"
end
field_definitions << "_meta?: { name: '#{type.name}'; query: Type#{type.name}QueryBase }"
<<~TYPE
export interface Type#{type.name} {
#{field_definitions.map { |line| " #{line}" }.join("\n")}
}
TYPE
end
end