ts_schema 0.2.1 → 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 +4 -4
- data/MIT-LICENSE +0 -0
- data/README.md +1 -0
- data/Rakefile +12 -1
- data/lib/generators/install_generator.rb +0 -0
- data/lib/generators/templates/ts_schema.rb +9 -15
- data/lib/tasks/ts_schema_tasks.rake +2 -0
- data/lib/ts_schema/configuration.rb +10 -7
- data/lib/ts_schema/conversion_table.yml +0 -0
- data/lib/ts_schema/railtie.rb +2 -0
- data/lib/ts_schema/schema_generator.rb +18 -20
- data/lib/ts_schema/version.rb +3 -1
- data/lib/ts_schema.rb +6 -5
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8795cf28b78a0558a5a8d5d602c340007625f8bfe1810cb34cb5bfdf6552f8b5
|
4
|
+
data.tar.gz: 14bd99114036a2115576d83325fe57c313d3f29a107d0b68eb93856893f4ef3e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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
|
#
|
@@ -82,28 +80,24 @@ TsSchema.setup do |config|
|
|
82
80
|
|
83
81
|
# Override types for fields by field name. This is globally applied.
|
84
82
|
# Useful for polymorphic associations which would otherwise be of type string, e.g.:
|
85
|
-
# commentable_type: "'Product'|'Review'"
|
83
|
+
# commentable_type: "'Product'|'Review'"
|
86
84
|
|
87
85
|
# config.field_type_overrides: {
|
88
86
|
|
89
87
|
# }
|
90
88
|
|
91
|
-
|
92
89
|
# Namespace for generated types
|
93
90
|
#
|
94
91
|
# config.namespace = :schema
|
95
92
|
|
96
|
-
|
97
93
|
# Output schema as types or interfaces: type|interface
|
98
94
|
#
|
99
95
|
# config.schema_type = :interface
|
100
96
|
|
101
|
-
|
102
97
|
# Indentation options: tab|space
|
103
98
|
#
|
104
99
|
# config.indent = :tab
|
105
100
|
|
106
|
-
|
107
101
|
# If indent is spaces, specify how many
|
108
102
|
#
|
109
103
|
# config.spaces = 2
|
@@ -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__)
|
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"],
|
@@ -21,13 +24,14 @@ module TsSchema
|
|
21
24
|
schema_type: :interface,
|
22
25
|
indent: :tab,
|
23
26
|
spaces: 2,
|
24
|
-
}
|
27
|
+
}.freeze
|
25
28
|
|
26
29
|
attr_accessor(*DEFAULTS.keys)
|
27
30
|
|
28
31
|
def initialize(attributes = nil)
|
29
32
|
assign(DEFAULTS)
|
30
33
|
return unless attributes
|
34
|
+
|
31
35
|
assign(attributes)
|
32
36
|
end
|
33
37
|
|
@@ -35,12 +39,11 @@ module TsSchema
|
|
35
39
|
if !attributes && !block
|
36
40
|
raise "Provide attributes or block"
|
37
41
|
end
|
42
|
+
|
38
43
|
tap(&block) if block
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
send(:"#{attribute}=", value)
|
43
|
-
end
|
44
|
+
attributes&.each do |attribute, value|
|
45
|
+
value = value.call if value.is_a?(Proc)
|
46
|
+
send(:"#{attribute}=", value)
|
44
47
|
end
|
45
48
|
self
|
46
49
|
end
|
File without changes
|
data/lib/ts_schema/railtie.rb
CHANGED
@@ -1,22 +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
12
|
@config.field_type_overrides = @config.field_type_overrides.stringify_keys
|
12
|
-
|
13
|
+
@models = []
|
13
14
|
|
14
15
|
Rails.application.eager_load!
|
15
|
-
|
16
|
-
|
17
|
-
|
16
|
+
@config.parent_classes.each do |parent|
|
17
|
+
@models.concat(get_subclasses(parent.to_s.constantize))
|
18
|
+
end
|
18
19
|
unless @config.additional_models.empty?
|
19
|
-
@models.concat(@config.additional_models.map do |m|
|
20
|
+
@models.concat(@config.additional_models.map do |m|
|
20
21
|
m.to_s.constantize
|
21
22
|
end)
|
22
23
|
end
|
@@ -41,9 +42,9 @@ module TsSchema
|
|
41
42
|
@models.each do |model|
|
42
43
|
columns = map_column_types(model)
|
43
44
|
columns.concat(map_associations(model)) if @config.include_associated
|
44
|
-
|
45
|
+
|
45
46
|
type_template += <<~TYPESCRIPT
|
46
|
-
#{@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 ? '= ' : ''}{
|
47
48
|
#{columns.map { |column| "#{indent_as_str}#{column_name_cased(column[:name])}: #{column[:ts_type]};" }.join("\n")}
|
48
49
|
}\n
|
49
50
|
TYPESCRIPT
|
@@ -63,9 +64,7 @@ module TsSchema
|
|
63
64
|
content = generate
|
64
65
|
return if File.exist?(path) && File.read(path) == content
|
65
66
|
|
66
|
-
File.
|
67
|
-
f.write content
|
68
|
-
end
|
67
|
+
File.write(path, content)
|
69
68
|
end
|
70
69
|
|
71
70
|
def map_column_types(model)
|
@@ -74,19 +73,19 @@ module TsSchema
|
|
74
73
|
next if @config.field_overrides[column_name] == :omit
|
75
74
|
|
76
75
|
type_override = config.field_type_overrides[column_name]
|
77
|
-
|
78
|
-
type = type_override
|
76
|
+
|
77
|
+
type = type_override || @types[column.type.to_s] || @config.default_type
|
79
78
|
name = map_name(column.name)
|
80
79
|
null = column.null
|
81
80
|
null = true if @config.field_overrides[name]&.to_s == "optional"
|
82
81
|
|
83
|
-
if(enum = model.defined_enums[name])
|
82
|
+
if (enum = model.defined_enums[name])
|
84
83
|
type = enum.keys.map { |k| "'#{k}'" }.join("|")
|
85
84
|
end
|
86
85
|
|
87
86
|
{
|
88
|
-
name: "#{name}#{
|
89
|
-
ts_type: "#{type}#{
|
87
|
+
name: "#{name}#{'?' if null}",
|
88
|
+
ts_type: "#{type}#{' | null' if @config.export_nulls && null}"
|
90
89
|
}
|
91
90
|
}.compact
|
92
91
|
end
|
@@ -105,13 +104,12 @@ module TsSchema
|
|
105
104
|
|
106
105
|
def map_associations(model)
|
107
106
|
model.reflect_on_all_associations.reject(&:polymorphic?).map do |association|
|
108
|
-
|
109
|
-
when association.has_one? || association.belongs_to?
|
107
|
+
if association.has_one? || association.belongs_to?
|
110
108
|
{
|
111
109
|
name: "#{association.name}?",
|
112
110
|
ts_type: association.class_name.constantize.model_name.param_key.camelize
|
113
111
|
}
|
114
|
-
|
112
|
+
elsif association.collection?
|
115
113
|
{
|
116
114
|
name: "#{association.name}?",
|
117
115
|
ts_type: "#{association.class_name.constantize.model_name.param_key.camelize}[]"
|
data/lib/ts_schema/version.rb
CHANGED
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
|
-
|
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
|
-
|
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.
|
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:
|
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.
|
81
|
+
rubygems_version: 3.3.7
|
82
82
|
signing_key:
|
83
83
|
specification_version: 4
|
84
84
|
summary: Generates typescript definitions from ActiveRecord
|