ts_schema 0.1.14 → 1.0.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e970a98bd2aea544c74c48dac67799e5b713ef56ab8eaa023662f2901973983a
4
- data.tar.gz: f259f07ed9fd61a06bf8b0c777df0a50696472534ba48f43737351a8982b3fb5
3
+ metadata.gz: 8795cf28b78a0558a5a8d5d602c340007625f8bfe1810cb34cb5bfdf6552f8b5
4
+ data.tar.gz: 14bd99114036a2115576d83325fe57c313d3f29a107d0b68eb93856893f4ef3e
5
5
  SHA512:
6
- metadata.gz: 30fcd65e0da2df3d5741fe12ed25f84139d3d94b1bc840661a9404105fe5a15e5a0f7a328817283c23592de13ab196d1d31df4398281c6a186d3afcef0d23eb4
7
- data.tar.gz: 1a44cc70e7acfb79209f03d2311eb368c1d128832c4e8f586c5ca7f7fa209d5f80641fd8ee57848f6e7b7f9573b1c97e399d372fcb8407b772dd4096b5d1be57
6
+ metadata.gz: 34e2a5851c811791eaabdcd8faff440d50aa185f226177082820d4cfacfc549eca74e0d5397fc64931b6ffe5284665bb3ac1513bfba0679ed1ba42ece97ba161
7
+ data.tar.gz: 4452a9c7c21247d714abcdf08e5c9711413b76bf48e559672f503156ec3edc9cefedc471637802524c2030c1de456fa464fd480004998865981582c93b885cf7
data/MIT-LICENSE CHANGED
File without changes
data/README.md CHANGED
@@ -62,6 +62,7 @@ rails ts_schema:generate
62
62
  |parent_classes |`["ApplicationRecord"]`|Array of string names of top level classes|Any class names included in this array will be querried for subclasses to generate types for|
63
63
  |additional_models |`[]`|Array of string names of ActiveRecord models|Add model names which don't inherit from classes included in `parent_classes`, but which should have types generated|
64
64
  |field_overrides |`{ encrypted_password: :password, password: :optional, }`|Hash of field names with the following values:<br/> `:optional`: Makes it an optional field by adding '?' to the defintion (example: password?: string)<br/>`:omit`: Omits the field from being output in the schema entirely<br/>`[string]`: Field name override. Will replace any instance of the hash key with the value. The default values replace `password` with `encrypted_password`|Overwrite, omit, or make optional any field name. Applies to all generated classes|
65
+ |field_type_overrides|`{}`|`{ field_name: 'typescriptType' }`|Override all instances of a field name in any record with the supplied type. Useful for polymorphic associations, for example: `commentable_type: "'Product'|'Review'"`|
65
66
  |namespace |`:schema`|string\|symbol|The typescript namespace to contain generated types|
66
67
  |schema_type |`:interface`|`:interface`\|`:type`|Whether to generate typescript definitions as types or interfaces. Interfaces are recommended since they are easier to extend|
67
68
  |indent|`:tab`|`:tab`\|`:space`|Indentation using tabs or spaces|
data/Rakefile CHANGED
@@ -1,3 +1,14 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "bundler/setup"
2
4
  require "bundler/gem_tasks"
3
- require "ts_schema"
5
+ require "ts_schema"
6
+ # require "rails/plugin/test"
7
+
8
+ # RSpec::Core::RakeTask.new(:test)
9
+
10
+ require "rubocop/rake_task"
11
+
12
+ RuboCop::RakeTask.new
13
+
14
+ task default: %i[rubocop]
File without changes
@@ -1,19 +1,18 @@
1
+ # frozen_string_literal: true
2
+
1
3
  TsSchema.setup do |config|
2
4
  # Case options for field names: camel|snake|pascal
3
5
  #
4
6
  # config.case = :camel
5
7
 
6
-
7
8
  # Customize output path and file name
8
9
  #
9
10
  # config.output = Rails.root.join('app', 'assets', 'javascripts', 'schema.d.ts')
10
11
 
11
-
12
12
  # Whether to generate the schema file after running migrations
13
13
  #
14
14
  # config.auto_generate = true
15
15
 
16
-
17
16
  # Add custom type mappings or overrides (as strings or symbols)
18
17
  #
19
18
  # Default type mappings:
@@ -37,20 +36,21 @@ TsSchema.setup do |config|
37
36
  # macaddr: string
38
37
  #
39
38
  # config.custom_types = {
40
- #
39
+ #
41
40
  # }
42
41
 
42
+ # Include null type for optional fields
43
+ #
44
+ # export_nulls = false
43
45
 
44
46
  # Default type for unrecognized types
45
47
  #
46
48
  # config.default_type = :string
47
49
 
48
-
49
50
  # Whether to generate types for associated models
50
51
  #
51
52
  # config.include_associated = true
52
53
 
53
-
54
54
  # Parent classes of models to generate (as strings or symbols)
55
55
  # Only classes inheriting from those in this list will have types generated
56
56
  #
@@ -58,15 +58,13 @@ TsSchema.setup do |config|
58
58
  # "ApplicationRecord",
59
59
  # ]
60
60
 
61
-
62
- # Additional models to generate schema from, such as those added by other gems
61
+ # Additional models to generate schema from, such as those added by other gems
63
62
  # which don't have a model file. (as strings or symbols)
64
63
  #
65
64
  # config.additional_models = [
66
- #
65
+ #
67
66
  # ]
68
67
 
69
-
70
68
  # Ignore certain fields, omitting them from the generated schema: :optional|(string)|false
71
69
  # Key is the name of the field to override options for.
72
70
  #
@@ -80,22 +78,26 @@ TsSchema.setup do |config|
80
78
  # password: :optional,
81
79
  # }
82
80
 
81
+ # Override types for fields by field name. This is globally applied.
82
+ # Useful for polymorphic associations which would otherwise be of type string, e.g.:
83
+ # commentable_type: "'Product'|'Review'"
84
+
85
+ # config.field_type_overrides: {
86
+
87
+ # }
83
88
 
84
89
  # Namespace for generated types
85
90
  #
86
91
  # config.namespace = :schema
87
92
 
88
-
89
93
  # Output schema as types or interfaces: type|interface
90
94
  #
91
95
  # config.schema_type = :interface
92
96
 
93
-
94
97
  # Indentation options: tab|space
95
98
  #
96
99
  # config.indent = :tab
97
100
 
98
-
99
101
  # If indent is spaces, specify how many
100
102
  #
101
103
  # config.spaces = 2
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "rake"
2
4
  require "ts_schema"
3
5
 
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "pathname"
2
4
 
3
5
  module TsSchema
@@ -6,8 +8,9 @@ module TsSchema
6
8
  case: :camel,
7
9
  output: -> { Rails.root.join('app', 'assets', 'javascripts', 'schema.d.ts') },
8
10
  auto_generate: true,
9
- types: ->{ YAML.load_file(File.expand_path(__dir__) + '/conversion_table.yml').to_h },
11
+ types: ->{ YAML.load_file("#{File.expand_path(__dir__)}/conversion_table.yml").to_h },
10
12
  custom_types: {},
13
+ export_nulls: false,
11
14
  default_type: :string,
12
15
  include_associated: true,
13
16
  parent_classes: ["ApplicationRecord"],
@@ -16,17 +19,19 @@ module TsSchema
16
19
  "encrypted_password" => :password,
17
20
  "password" => :optional,
18
21
  },
22
+ field_type_overrides: {},
19
23
  namespace: :schema,
20
24
  schema_type: :interface,
21
25
  indent: :tab,
22
26
  spaces: 2,
23
- }
27
+ }.freeze
24
28
 
25
29
  attr_accessor(*DEFAULTS.keys)
26
30
 
27
31
  def initialize(attributes = nil)
28
32
  assign(DEFAULTS)
29
33
  return unless attributes
34
+
30
35
  assign(attributes)
31
36
  end
32
37
 
@@ -34,12 +39,11 @@ module TsSchema
34
39
  if !attributes && !block
35
40
  raise "Provide attributes or block"
36
41
  end
42
+
37
43
  tap(&block) if block
38
- if attributes
39
- attributes.each do |attribute, value|
40
- value = value.call if value.is_a?(Proc)
41
- send(:"#{attribute}=", value)
42
- end
44
+ attributes&.each do |attribute, value|
45
+ value = value.call if value.is_a?(Proc)
46
+ send(:"#{attribute}=", value)
43
47
  end
44
48
  self
45
49
  end
File without changes
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "rails"
2
4
 
3
5
  module TsSchema
@@ -1,21 +1,23 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'fileutils'
2
4
 
3
5
  module TsSchema
4
6
  class SchemaGenerator
5
- attr_accessor :config
6
- attr_accessor :models
7
+ attr_accessor :config, :models
7
8
 
8
9
  def initialize(config = nil)
9
10
  @config = config || TsSchema::Configuration.new
10
11
  @config.field_overrides = @config.field_overrides.stringify_keys
11
- @models = []
12
+ @config.field_type_overrides = @config.field_type_overrides.stringify_keys
13
+ @models = []
12
14
 
13
15
  Rails.application.eager_load!
14
- @config.parent_classes.each do |parent|
15
- @models.concat(get_subclasses(parent.to_s.constantize))
16
- end
16
+ @config.parent_classes.each do |parent|
17
+ @models.concat(get_subclasses(parent.to_s.constantize))
18
+ end
17
19
  unless @config.additional_models.empty?
18
- @models.concat(@config.additional_models.map do |m|
20
+ @models.concat(@config.additional_models.map do |m|
19
21
  m.to_s.constantize
20
22
  end)
21
23
  end
@@ -40,9 +42,9 @@ module TsSchema
40
42
  @models.each do |model|
41
43
  columns = map_column_types(model)
42
44
  columns.concat(map_associations(model)) if @config.include_associated
43
-
45
+
44
46
  type_template += <<~TYPESCRIPT
45
- #{@config.schema_type} #{model.model_name.param_key.camelize} #{@config.schema_type.to_sym == :type ? "= " : ""}{
47
+ #{@config.schema_type} #{model.model_name.param_key.camelize} #{@config.schema_type.to_sym == :type ? '= ' : ''}{
46
48
  #{columns.map { |column| "#{indent_as_str}#{column_name_cased(column[:name])}: #{column[:ts_type]};" }.join("\n")}
47
49
  }\n
48
50
  TYPESCRIPT
@@ -62,27 +64,28 @@ module TsSchema
62
64
  content = generate
63
65
  return if File.exist?(path) && File.read(path) == content
64
66
 
65
- File.open(path, 'w') do |f|
66
- f.write content
67
- end
67
+ File.write(path, content)
68
68
  end
69
69
 
70
70
  def map_column_types(model)
71
- model.columns.map { |i|
72
- next if @config.field_overrides[i.name.to_s] == :omit
71
+ model.columns.map { |column|
72
+ column_name = column.name.to_s
73
+ next if @config.field_overrides[column_name] == :omit
74
+
75
+ type_override = config.field_type_overrides[column_name]
73
76
 
74
- type = @types[i.type.to_s] || @config.default_type
75
- name = map_name(i.name)
76
- null = i.null
77
+ type = type_override || @types[column.type.to_s] || @config.default_type
78
+ name = map_name(column.name)
79
+ null = column.null
77
80
  null = true if @config.field_overrides[name]&.to_s == "optional"
78
81
 
79
- if(enum = model.defined_enums[name])
82
+ if (enum = model.defined_enums[name])
80
83
  type = enum.keys.map { |k| "'#{k}'" }.join("|")
81
84
  end
82
85
 
83
86
  {
84
- name: "#{name}#{"?" if null }",
85
- ts_type: "#{type}#{" | null" if null}"
87
+ name: "#{name}#{'?' if null}",
88
+ ts_type: "#{type}#{' | null' if @config.export_nulls && null}"
86
89
  }
87
90
  }.compact
88
91
  end
@@ -101,13 +104,12 @@ module TsSchema
101
104
 
102
105
  def map_associations(model)
103
106
  model.reflect_on_all_associations.reject(&:polymorphic?).map do |association|
104
- case
105
- when association.has_one? || association.belongs_to?
107
+ if association.has_one? || association.belongs_to?
106
108
  {
107
109
  name: "#{association.name}?",
108
110
  ts_type: association.class_name.constantize.model_name.param_key.camelize
109
111
  }
110
- when association.collection?
112
+ elsif association.collection?
111
113
  {
112
114
  name: "#{association.name}?",
113
115
  ts_type: "#{association.class_name.constantize.model_name.param_key.camelize}[]"
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module TsSchema
2
- VERSION = "0.1.14"
4
+ VERSION = "1.0.0"
3
5
  end
data/lib/ts_schema.rb CHANGED
@@ -1,10 +1,11 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "ts_schema/version"
2
4
  require "ts_schema/railtie"
3
5
 
4
6
  require "ts_schema/configuration"
5
7
  require "ts_schema/schema_generator"
6
8
 
7
-
8
9
  module TsSchema
9
10
  class << self
10
11
  def setup(&block)
@@ -18,18 +19,18 @@ module TsSchema
18
19
  def generate
19
20
  if ActiveRecord::Base.connection.migration_context.needs_migration?
20
21
  puts "Aborting: There are pending migrations"
21
- else
22
+ else
22
23
  SchemaGenerator.new(@configuration).generate
23
24
  end
24
25
  end
25
26
 
26
- def output_file
27
+ def output_file
27
28
  if ActiveRecord::Base.connection.migration_context.needs_migration?
28
29
  puts "Aborting: There are pending migrations"
29
- else
30
+ else
30
31
  SchemaGenerator.new(@configuration).output_file
31
32
  end
32
- end
33
+ end
33
34
  end
34
35
  end
35
36
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ts_schema
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.14
4
+ version: 1.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Avram Walden
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-07-09 00:00:00.000000000 Z
11
+ date: 2023-03-18 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -78,7 +78,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
78
78
  - !ruby/object:Gem::Version
79
79
  version: '0'
80
80
  requirements: []
81
- rubygems_version: 3.2.32
81
+ rubygems_version: 3.3.7
82
82
  signing_key:
83
83
  specification_version: 4
84
84
  summary: Generates typescript definitions from ActiveRecord