Skip to content

Commit

Permalink
Add a TypeGenerator for custom non-model types (enums, aliases, etc)
Browse files Browse the repository at this point in the history
  • Loading branch information
azimux committed Aug 22, 2024
1 parent bb5b5ed commit 07a686e
Show file tree
Hide file tree
Showing 8 changed files with 173 additions and 71 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
## [0.0.2] - 2024-08-21

- Add a TypeGenerator for custom non-model types

## [0.0.1] - 2024-06-17

- Add Apache-2.0 license
Expand Down
28 changes: 14 additions & 14 deletions Gemfile.lock
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
PATH
remote: .
specs:
foobara-typescript-remote-command-generator (0.0.1)
foobara-typescript-remote-command-generator (0.0.2)
foobara
foobara-files-generator

Expand All @@ -12,13 +12,13 @@ GEM
byebug (11.1.3)
coderay (1.1.3)
diff-lcs (1.5.1)
docile (1.4.0)
docile (1.4.1)
ffi (1.17.0-x86_64-linux-gnu)
foobara (0.0.1)
foobara (0.0.7)
foobara-util
foobara-files-generator (0.0.1)
foobara-files-generator (0.0.3)
foobara
foobara-rubocop-rules (0.0.3)
foobara-rubocop-rules (0.0.4)
rubocop
rubocop-rspec
foobara-spec-helpers (0.0.3)
Expand Down Expand Up @@ -50,8 +50,8 @@ GEM
notiffany (0.1.3)
nenv (~> 0.1)
shellany (~> 0.0)
parallel (1.25.1)
parser (3.3.3.0)
parallel (1.26.3)
parser (3.3.4.2)
ast (~> 2.4.1)
racc
pry (0.14.2)
Expand All @@ -60,22 +60,22 @@ GEM
pry-byebug (3.10.1)
byebug (~> 11.0)
pry (>= 0.13, < 0.15)
racc (1.8.0)
racc (1.8.1)
rainbow (3.1.1)
rake (13.2.1)
rb-fsevent (0.11.2)
rb-inotify (0.11.1)
ffi (~> 1.0)
regexp_parser (2.9.2)
rexml (3.3.0)
rexml (3.3.6)
strscan
rspec (3.13.0)
rspec-core (~> 3.13.0)
rspec-expectations (~> 3.13.0)
rspec-mocks (~> 3.13.0)
rspec-core (3.13.0)
rspec-support (~> 3.13.0)
rspec-expectations (3.13.1)
rspec-expectations (3.13.2)
diff-lcs (>= 1.2.0, < 2.0)
rspec-support (~> 3.13.0)
rspec-its (1.3.0)
Expand All @@ -85,22 +85,22 @@ GEM
diff-lcs (>= 1.2.0, < 2.0)
rspec-support (~> 3.13.0)
rspec-support (3.13.1)
rubocop (1.64.1)
rubocop (1.65.1)
json (~> 2.3)
language_server-protocol (>= 3.17.0)
parallel (~> 1.10)
parser (>= 3.3.0.2)
rainbow (>= 2.2.2, < 4.0)
regexp_parser (>= 1.8, < 3.0)
regexp_parser (>= 2.4, < 3.0)
rexml (>= 3.2.5, < 4.0)
rubocop-ast (>= 1.31.1, < 2.0)
ruby-progressbar (~> 1.7)
unicode-display_width (>= 2.4.0, < 3.0)
rubocop-ast (1.31.3)
rubocop-ast (1.32.1)
parser (>= 3.3.1.0)
rubocop-rake (0.6.0)
rubocop (~> 1.0)
rubocop-rspec (3.0.1)
rubocop-rspec (3.0.4)
rubocop (~> 1.61)
ruby-progressbar (1.13.0)
shellany (0.0.1)
Expand Down
12 changes: 4 additions & 8 deletions src/remote_generator/services/command_inputs_generator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -14,18 +14,14 @@ def template_path
"Command/Inputs.ts.erb"
end

def model_generators
@model_generators ||= inputs_types_depended_on.select(&:model?).uniq.map do |model|
if model.entity?
Services::EntityGenerator.new(model)
else
Services::ModelGenerator.new(model)
end
def type_generators
@type_generators ||= inputs_types_depended_on.reject(&:builtin?).uniq.map do |type|
TypeGenerator.new(type)
end
end

def dependencies
model_generators
type_generators
end
end
end
Expand Down
52 changes: 4 additions & 48 deletions src/remote_generator/services/model_generator.rb
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
require_relative "typescript_from_manifest_base_generator"
require_relative "type_generator"

module Foobara
module RemoteGenerator
class Services
class ModelGenerator < TypescriptFromManifestBaseGenerator
class ModelGenerator < TypeGenerator
class << self
def new(relevant_manifest)
return super unless self == ModelGenerator
Expand All @@ -26,57 +27,12 @@ def template_path
["Model", "Model.ts.erb"]
end

def scoped_full_path(points = nil)
full_path = model_manifest.scoped_full_path

if points
start_at = full_path.size - points - 1
full_path[start_at..]
else
full_path
end
end

def model_name(points = nil)
if points
scoped_full_path(points).join(".")
else
scoped_path.join(".")
end
end

# Do models have associations??
def model_generators
types_depended_on.select(&:model?).map do |model|
Services::ModelGenerator.new(model)
end
end

def dependencies
model_generators
type_name(points)
end

def model_name_downcase
model_name[0].downcase + model_name[1..]
end

def attributes_type_ts_type
association_depth = AssociationDepth::AMBIGUOUS
foobara_type_to_ts_type(attributes_type, association_depth:, dependency_group:)
end

def atom_attributes_ts_type
association_depth = AssociationDepth::ATOM
foobara_type_to_ts_type(attributes_type, association_depth:, dependency_group:)
end

def aggregate_attributes_ts_type
association_depth = AssociationDepth::AGGREGATE
foobara_type_to_ts_type(attributes_type, association_depth:, dependency_group:)
end

def attribute_names
attributes_type.attribute_names
type_name_downcase
end
end
end
Expand Down
112 changes: 112 additions & 0 deletions src/remote_generator/services/type_generator.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
require_relative "typescript_from_manifest_base_generator"

module Foobara
module RemoteGenerator
class Services
class TypeGenerator < TypescriptFromManifestBaseGenerator
class << self
def new(relevant_manifest)
return super unless self == TypeGenerator

if relevant_manifest.entity?
EntityGenerator.new(relevant_manifest)
elsif relevant_manifest.model?
ModelGenerator.new(relevant_manifest)
else
super
end
end
end

alias type_manifest relevant_manifest

def target_path
[*domain.scoped_full_path, "types", "#{type_name}.ts"]
end

def template_path
["Type", "Type.ts.erb"]
end

def scoped_full_path(points = nil)
full_path = type_manifest.scoped_full_path

if points
start_at = full_path.size - points - 1
full_path[start_at..]
else
full_path
end
end

def type_name(points = nil)
if points
scoped_full_path(points).join(".")
else
scoped_path.join(".")
end
end

def type_guts
guts = if declaration_data.key?("one_of")
declaration_data["one_of"].map do |enum_item|
value_to_ts_value(enum_item)
end.join(" | ")
else
# :nocov:
raise "Haven't implemented other types yet"
# :nocov:
end

if declaration_data["allows_nil"]
# TODO: add a custom type to the fixture manifest that includes allows_nil
# :nocov:
guts += " | undefined"
# :nocov:
end

guts
end

def model_generators
@model_generators ||= types_depended_on.select(&:model?).map do |model|
Services::ModelGenerator.new(model)
end
end

def custom_type_generators
@custom_type_generators ||= types_depended_on.reject(&:builtin?).reject(&:model?).map do |type|
Services::TypeGenerator.new(type)
end
end

def dependencies
custom_type_generators + model_generators
end

def type_name_downcase
type_name[0].downcase + type_name[1..]
end

def attributes_type_ts_type
association_depth = AssociationDepth::AMBIGUOUS
foobara_type_to_ts_type(attributes_type, association_depth:, dependency_group:)
end

def atom_attributes_ts_type
association_depth = AssociationDepth::ATOM
foobara_type_to_ts_type(attributes_type, association_depth:, dependency_group:)
end

def aggregate_attributes_ts_type
association_depth = AssociationDepth::AGGREGATE
foobara_type_to_ts_type(attributes_type, association_depth:, dependency_group:)
end

def attribute_names
attributes_type.attribute_names
end
end
end
end
end
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,8 @@ def manifest_to_generator_classes(manifest)
Services::ProcessorClassGenerator
when Manifest::RootManifest
Services::RootManifestGenerator
when Manifest::Type
Services::TypeGenerator
else
# :nocov:
raise "Not sure how build a generator for a #{manifest}"
Expand Down Expand Up @@ -224,6 +226,10 @@ def foobara_type_to_ts_type(
else
if type_declaration.model?
model_to_ts_model_name(type_declaration, association_depth:, initial:)
elsif can_convert_type_declaration_to_ts_type?(type_declaration)
type = type_declaration.to_type

custom_type_to_ts_type_name(type)
end
end
end
Expand All @@ -245,6 +251,22 @@ def foobara_type_to_ts_type(
end
end

def can_convert_type_declaration_to_ts_type?(type_declaration)
type = type_declaration.to_type

return false if BuiltinTypes.builtin_reference?(type.reference)

allowed_keys = %w[type one_of allows_nil]

declaration_data = type.declaration_data

bad_keys = declaration_data.keys - allowed_keys

return false unless bad_keys.empty?

BuiltinTypes.builtin_reference?(declaration_data["type"])
end

def attributes_to_ts_type(attributes, dependency_group:, association_depth: AssociationDepth::AMBIGUOUS)
guts = attributes.attribute_declarations.map do |attribute_name, attribute_declaration|
" #{attribute_name}#{"?" unless attributes.required?(attribute_name)}: #{
Expand Down Expand Up @@ -280,6 +302,13 @@ def model_to_ts_model_name(model, association_depth: AssociationDepth::AMBIGUOUS
dependency_group.non_colliding_type(generator)
end

def custom_type_to_ts_type_name(type)
type = type.to_type if type.is_a?(Manifest::TypeDeclaration)
generator = TypeGenerator.new(type)

dependency_group.non_colliding_type(generator)
end

def ==(other)
self.class == other.class && path == other.path && root_manifest == other.root_manifest
end
Expand Down
5 changes: 5 additions & 0 deletions templates/Type/Type.ts.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<% dependency_roots.each do |dependency_root| %>
import { <%= dependency_root.ts_instance_name %> } from "<%= path_to_root %><%= dependency_root.import_path %>"
<% end %>

export type <%= type_name %> = <%= type_guts %>
2 changes: 1 addition & 1 deletion version.rb
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
module Foobara
module TypescriptRemoteCommandGenerator
module Version
VERSION = "0.0.1".freeze
VERSION = "0.0.2".freeze
end
end
end

0 comments on commit 07a686e

Please sign in to comment.