ts_schema 0.1.10 → 0.1.13
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 +3 -3
- data/Rakefile +1 -0
- data/lib/generators/install_generator.rb +0 -0
- data/lib/generators/templates/ts_schema.rb +76 -31
- data/lib/tasks/ts_schema_tasks.rake +6 -13
- data/lib/ts_schema/configuration.rb +7 -2
- data/lib/ts_schema/conversion_table.yml +0 -2
- data/lib/ts_schema/railtie.rb +3 -0
- data/lib/ts_schema/schema_generator.rb +76 -36
- data/lib/ts_schema/version.rb +1 -1
- data/lib/ts_schema.rb +11 -3
- metadata +19 -6
- data/lib/generators/generate_generator.rb +0 -17
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8d6e690832a89b7cbde62be4a27e6dc9374be937df6627bff391db15c2f1e777
|
4
|
+
data.tar.gz: 9a6aec0dd27e0938cdd856ad723dc28898a582de67122b7ed9bc147ed6d335c6
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7df830e6e1a3543944f9550e57801f16c9ef2121462983c67944814e70f21c47f48b8fe6d5841286c92d1876cee50c8b32bf1533a49ae90f436234ed52723bcd
|
7
|
+
data.tar.gz: 1cc1c840bef030c08afee4480102d6a4cbda128d30c1de01969ad9b03312c9f71f3019c589ea382e23756ba267f0ab939bc839f62c79619381d7535e9be33de7
|
data/MIT-LICENSE
CHANGED
File without changes
|
data/README.md
CHANGED
@@ -16,9 +16,9 @@ rails generate ts_schema:install
|
|
16
16
|
|
17
17
|
## Usage
|
18
18
|
|
19
|
-
All options with their defaults are in the
|
19
|
+
All options with their defaults are in the generated initializer file.
|
20
20
|
|
21
|
-
By default, every migration
|
21
|
+
By default, every migration will auto generate a new schema file, replacing the existing one. You can disable this behavior in the config file.
|
22
22
|
|
23
23
|
You can manually generate the schema file by running:
|
24
24
|
|
@@ -28,7 +28,7 @@ rails ts_schema:generate
|
|
28
28
|
|
29
29
|
## Gotchas
|
30
30
|
|
31
|
-
|
31
|
+
Sometimes ActiveRecord's inflections will alter the class name. For instance, with a class named `Five`; `"Fives".singularize` returns "Fife", which is not the classname. In the case where Rails alters the classname for an association, you must explicitly define it on the association in the model using `class_name`. Example: `has_many :fives, class_name: "Five"`.
|
32
32
|
|
33
33
|
## License
|
34
34
|
|
data/Rakefile
CHANGED
File without changes
|
@@ -1,57 +1,102 @@
|
|
1
|
+
# Default type mappings:
|
2
|
+
#
|
3
|
+
# string: string
|
4
|
+
# text: string
|
5
|
+
# integer: number
|
6
|
+
# enum: number
|
7
|
+
# bigint: number
|
8
|
+
# float: number
|
9
|
+
# decimal: number
|
10
|
+
# json: Record<string, any>
|
11
|
+
# jsonb: Record<string, any>
|
12
|
+
# binary: string
|
13
|
+
# boolean: boolean
|
14
|
+
# date: string
|
15
|
+
# datetime: string
|
16
|
+
# timestamp: string
|
17
|
+
# datetime_with_timezone: string
|
18
|
+
# inet: string
|
19
|
+
# cidr: string
|
20
|
+
# macaddr: string
|
21
|
+
|
1
22
|
TsSchema.setup do |config|
|
2
|
-
#
|
23
|
+
# Case options: camel|snake|pascal
|
24
|
+
#
|
3
25
|
# config.case = :camel
|
4
26
|
|
27
|
+
|
5
28
|
# Customize output path and file name
|
29
|
+
#
|
6
30
|
# config.output = Rails.root.join('app', 'assets', 'javascripts', 'schema.d.ts')
|
7
31
|
|
8
|
-
|
32
|
+
|
33
|
+
# Whether to generate the schema file after running migrations
|
34
|
+
#
|
9
35
|
# config.auto_generate = true
|
10
36
|
|
37
|
+
|
11
38
|
# Add custom type mappings or overrides
|
12
|
-
|
13
|
-
# Default type mappings:
|
14
|
-
#
|
15
|
-
# string: string
|
16
|
-
# text: string
|
17
|
-
# integer: number
|
18
|
-
# enum: number
|
19
|
-
# bigint: number
|
20
|
-
# float: number
|
21
|
-
# decimal: number
|
22
|
-
# json: Record<string, any>
|
23
|
-
# jsonb: Record<string, any>
|
24
|
-
# binary: string
|
25
|
-
# boolean: boolean
|
26
|
-
# date: string
|
27
|
-
# datetime: string
|
28
|
-
# timestamp: string
|
29
|
-
# datetime_with_timezone: string
|
30
|
-
# inet: string
|
31
|
-
# cidr: string
|
32
|
-
# macaddr: string
|
33
|
-
#
|
39
|
+
#
|
34
40
|
# config.custom_types = {
|
35
41
|
#
|
36
42
|
# }
|
37
43
|
|
44
|
+
|
38
45
|
# Default type for unrecognized types
|
46
|
+
#
|
39
47
|
# config.default_type = :string
|
40
48
|
|
41
|
-
|
49
|
+
|
50
|
+
# Whether to generate types for associated models
|
51
|
+
#
|
42
52
|
# config.include_associated = true
|
43
53
|
|
44
|
-
# Additional models to map which don't have a model file
|
45
|
-
# config.additional_models = [
|
46
|
-
#
|
47
|
-
# ]
|
48
54
|
|
49
|
-
#
|
55
|
+
# Parent classes of models to generate (as strings or symbols)
|
56
|
+
# Only classes inheriting from those in this list will have types generated
|
57
|
+
#
|
58
|
+
# config.parent_classes = [
|
59
|
+
# "ApplicationRecord",
|
60
|
+
# ]
|
61
|
+
|
62
|
+
|
63
|
+
# Additional models to generate schema from, such as those added by other gems
|
64
|
+
# which don't have a model file. (as strings or symbols)
|
65
|
+
#
|
66
|
+
# config.additional_models = [
|
67
|
+
#
|
68
|
+
# ]
|
69
|
+
|
70
|
+
|
71
|
+
# Ignore certain fields, omitting them from the generated schema: :optional|(string)|false
|
72
|
+
# Key is the name of the field to override options for.
|
73
|
+
# [:optional] will make this an optional field by adding '?' to the defintion (example: password?: string)
|
74
|
+
# [(string)] enter a field name override, for instance rename encrypted_password to password
|
75
|
+
# In that scenario, also specifying passwoord as an optional field will append a ? in the output
|
76
|
+
# [:omit] will omit the field from being output in the schema entirely
|
77
|
+
#
|
78
|
+
# config.field_overrides: {
|
79
|
+
# encrypted_password: :password,
|
80
|
+
# password: :optional,
|
81
|
+
# }
|
82
|
+
|
83
|
+
|
84
|
+
# Namespace for generated types
|
85
|
+
#
|
50
86
|
# config.namespace = :schema
|
51
87
|
|
52
|
-
|
88
|
+
|
89
|
+
# Output schema as types or interfaces: type|interface
|
90
|
+
#
|
91
|
+
# config.schema_type = :interface
|
92
|
+
|
93
|
+
|
94
|
+
# Indentation options: tab|space
|
95
|
+
#
|
53
96
|
# config.indent = :tab
|
54
97
|
|
98
|
+
|
55
99
|
# If indent is spaces, specify how many
|
100
|
+
#
|
56
101
|
# config.spaces = 2
|
57
102
|
end
|
@@ -1,8 +1,9 @@
|
|
1
1
|
require "rake"
|
2
|
+
require "ts_schema"
|
2
3
|
|
3
4
|
namespace :ts_schema do
|
4
5
|
desc "Generates a schema file in the default javascripts location, or the location specified in the ts_config initializer options"
|
5
|
-
task :
|
6
|
+
task generate: :environment do
|
6
7
|
TsSchema.output_file
|
7
8
|
end
|
8
9
|
end
|
@@ -12,19 +13,11 @@ namespace :db do
|
|
12
13
|
TsSchema.output_file if TsSchema.configuration.auto_generate
|
13
14
|
end
|
14
15
|
|
15
|
-
task migrate
|
16
|
-
auto_generate_and_save_file
|
16
|
+
task :migrate do
|
17
|
+
at_exit { auto_generate_and_save_file }
|
17
18
|
end
|
18
19
|
|
19
|
-
task
|
20
|
-
auto_generate_and_save_file
|
21
|
-
end
|
22
|
-
|
23
|
-
task reset: :environment do
|
24
|
-
auto_generate_and_save_file
|
25
|
-
end
|
26
|
-
|
27
|
-
task setup: :environment do
|
28
|
-
auto_generate_and_save_file
|
20
|
+
task :setup do
|
21
|
+
at_exit { auto_generate_and_save_file }
|
29
22
|
end
|
30
23
|
end
|
@@ -10,10 +10,16 @@ module TsSchema
|
|
10
10
|
custom_types: {},
|
11
11
|
default_type: :string,
|
12
12
|
include_associated: true,
|
13
|
+
parent_classes: ["ApplicationRecord"],
|
14
|
+
additional_models: [],
|
15
|
+
field_overrides: {
|
16
|
+
"encrypted_password" => :password,
|
17
|
+
"password" => :optional,
|
18
|
+
},
|
13
19
|
namespace: :schema,
|
20
|
+
schema_type: :interface,
|
14
21
|
indent: :tab,
|
15
22
|
spaces: 2,
|
16
|
-
additional_models: []
|
17
23
|
}
|
18
24
|
|
19
25
|
attr_accessor(*DEFAULTS.keys)
|
@@ -37,6 +43,5 @@ module TsSchema
|
|
37
43
|
end
|
38
44
|
self
|
39
45
|
end
|
40
|
-
|
41
46
|
end
|
42
47
|
end
|
@@ -2,7 +2,6 @@ string: string
|
|
2
2
|
text: string
|
3
3
|
integer: number
|
4
4
|
enum: number
|
5
|
-
bigint: number
|
6
5
|
float: number
|
7
6
|
decimal: number
|
8
7
|
json: Record<string, any>
|
@@ -12,7 +11,6 @@ boolean: boolean
|
|
12
11
|
date: string
|
13
12
|
datetime: string
|
14
13
|
timestamp: string
|
15
|
-
datetime_with_timezone: string
|
16
14
|
inet: string
|
17
15
|
cidr: string
|
18
16
|
macaddr: string
|
data/lib/ts_schema/railtie.rb
CHANGED
@@ -2,65 +2,99 @@ require 'fileutils'
|
|
2
2
|
|
3
3
|
module TsSchema
|
4
4
|
class SchemaGenerator
|
5
|
-
|
5
|
+
attr_accessor :config
|
6
|
+
attr_accessor :models
|
7
|
+
|
8
|
+
def initialize(config = nil)
|
9
|
+
@config = config || TsSchema::Configuration.new
|
10
|
+
@config.field_overrides = @config.field_overrides.stringify_keys
|
11
|
+
@models = []
|
12
|
+
|
6
13
|
Rails.application.eager_load!
|
7
|
-
|
8
|
-
|
9
|
-
@models.concat(TsSchema.configuration.additional_models.map {|m| m.to_s.constantize })
|
14
|
+
@config.parent_classes.each do |parent|
|
15
|
+
@models.concat(get_subclasses(parent.to_s.constantize))
|
10
16
|
end
|
11
|
-
@
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
17
|
+
unless @config.additional_models.empty?
|
18
|
+
@models.concat(@config.additional_models.map do |m|
|
19
|
+
m.to_s.constantize
|
20
|
+
end)
|
21
|
+
end
|
22
|
+
@types = @config.types.stringify_keys.merge(@config.custom_types.stringify_keys || {})
|
16
23
|
end
|
17
24
|
|
18
|
-
def
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
File.open(path, 'w') do |f|
|
26
|
-
f.write content
|
25
|
+
def get_subclasses(model)
|
26
|
+
models = model.send(:subclasses)
|
27
|
+
unless nested_empty?(models)
|
28
|
+
models.concat(models.flat_map do |m|
|
29
|
+
get_subclasses(m)
|
30
|
+
end)
|
27
31
|
end
|
32
|
+
models
|
28
33
|
end
|
29
34
|
|
30
|
-
|
31
|
-
|
32
|
-
def generate_typescript
|
35
|
+
def generate
|
33
36
|
type_template = ""
|
37
|
+
|
34
38
|
@models.each do |model|
|
35
39
|
columns = map_column_types(model)
|
36
|
-
columns.concat(map_associations(model)) if
|
40
|
+
columns.concat(map_associations(model)) if @config.include_associated
|
37
41
|
|
38
42
|
type_template += <<~TYPESCRIPT
|
39
|
-
|
43
|
+
#{@config.schema_type} #{model.model_name.param_key.camelize} #{@config.schema_type.to_sym == :type ? "= " : ""}{
|
40
44
|
#{columns.map { |column| "#{indent_as_str}#{column_name_cased(column[:name])}: #{column[:ts_type]};" }.join("\n")}
|
41
45
|
}\n
|
42
46
|
TYPESCRIPT
|
43
47
|
end
|
48
|
+
|
44
49
|
type_template = <<~TPL
|
45
|
-
declare namespace #{
|
50
|
+
declare namespace #{@config.namespace} {
|
46
51
|
#{indent_wrapper(type_template)}
|
47
52
|
}
|
48
53
|
TPL
|
49
54
|
end
|
50
55
|
|
56
|
+
def output_file
|
57
|
+
path = @config.output
|
58
|
+
FileUtils.mkdir_p(File.dirname(path))
|
59
|
+
|
60
|
+
content = generate
|
61
|
+
return if File.exist?(path) && File.read(path) == content
|
62
|
+
|
63
|
+
File.open(path, 'w') do |f|
|
64
|
+
f.write content
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
51
68
|
def map_column_types(model)
|
52
69
|
model.columns.map { |i|
|
53
|
-
|
70
|
+
next if @config.field_overrides[i.name.to_s] == :omit
|
54
71
|
|
55
|
-
|
56
|
-
|
72
|
+
type = @types[i.type.to_s] || @config.default_type
|
73
|
+
name = map_name(i.name)
|
74
|
+
null = i.null
|
75
|
+
null = true if @config.field_overrides[name]&.to_s == "optional"
|
76
|
+
|
77
|
+
if(enum = model.defined_enums[name])
|
78
|
+
type = enum.keys.map { |k| "'#{k}'" }.join("|")
|
57
79
|
end
|
58
|
-
|
80
|
+
|
59
81
|
{
|
60
|
-
name: "#{
|
61
|
-
ts_type: "#{type}#{" | null" if
|
82
|
+
name: "#{name}#{"?" if null }",
|
83
|
+
ts_type: "#{type}#{" | null" if null}"
|
62
84
|
}
|
63
|
-
}
|
85
|
+
}.compact
|
86
|
+
end
|
87
|
+
|
88
|
+
def map_name(name)
|
89
|
+
final_name = name.to_s
|
90
|
+
return final_name unless @config.field_overrides[final_name]
|
91
|
+
|
92
|
+
if @config.field_overrides[final_name]&.to_s != "optional"
|
93
|
+
final_name = @config.field_overrides[final_name]&.to_s
|
94
|
+
|
95
|
+
final_name = map_name(final_name) if @config.field_overrides[final_name]
|
96
|
+
end
|
97
|
+
final_name
|
64
98
|
end
|
65
99
|
|
66
100
|
def map_associations(model)
|
@@ -80,8 +114,14 @@ module TsSchema
|
|
80
114
|
end
|
81
115
|
end
|
82
116
|
|
117
|
+
private
|
118
|
+
|
119
|
+
def nested_empty?(arr)
|
120
|
+
arr.is_a?(Array) && arr.flatten.empty?
|
121
|
+
end
|
122
|
+
|
83
123
|
def column_name_cased(name)
|
84
|
-
case
|
124
|
+
case @config.case.to_sym
|
85
125
|
when :camel
|
86
126
|
name.camelize(:lower)
|
87
127
|
when :pascal
|
@@ -92,18 +132,18 @@ module TsSchema
|
|
92
132
|
end
|
93
133
|
|
94
134
|
def indent_as_str
|
95
|
-
case
|
135
|
+
case @config.indent.to_sym
|
96
136
|
when :space || :spaces
|
97
|
-
"".rjust(
|
137
|
+
"".rjust(@config.spaces, " ")
|
98
138
|
else
|
99
139
|
"\t"
|
100
140
|
end
|
101
141
|
end
|
102
142
|
|
103
143
|
def indent_wrapper(str)
|
104
|
-
case
|
144
|
+
case @config.indent.to_sym
|
105
145
|
when :space || :spaces
|
106
|
-
str.indent(
|
146
|
+
str.indent(@config.spaces)
|
107
147
|
else
|
108
148
|
str.indent(1, "\t")
|
109
149
|
end
|
data/lib/ts_schema/version.rb
CHANGED
data/lib/ts_schema.rb
CHANGED
@@ -4,6 +4,7 @@ require "ts_schema/railtie"
|
|
4
4
|
require "ts_schema/configuration"
|
5
5
|
require "ts_schema/schema_generator"
|
6
6
|
|
7
|
+
|
7
8
|
module TsSchema
|
8
9
|
class << self
|
9
10
|
def setup(&block)
|
@@ -15,14 +16,21 @@ module TsSchema
|
|
15
16
|
end
|
16
17
|
|
17
18
|
def generate
|
18
|
-
|
19
|
+
if ActiveRecord::Base.connection.migration_context.needs_migration?
|
20
|
+
puts "Aborting: There are pending migrations"
|
21
|
+
else
|
22
|
+
SchemaGenerator.new(@configuration).generate
|
23
|
+
end
|
19
24
|
end
|
20
25
|
|
21
26
|
def output_file
|
22
|
-
|
27
|
+
if ActiveRecord::Base.connection.migration_context.needs_migration?
|
28
|
+
puts "Aborting: There are pending migrations"
|
29
|
+
else
|
30
|
+
SchemaGenerator.new(@configuration).output_file
|
31
|
+
end
|
23
32
|
end
|
24
33
|
end
|
25
34
|
end
|
26
35
|
|
27
36
|
require "generators/install_generator"
|
28
|
-
require "generators/generate_generator"
|
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.
|
4
|
+
version: 0.1.13
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Avram Walden
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2022-04-
|
11
|
+
date: 2022-04-08 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|
@@ -24,6 +24,20 @@ dependencies:
|
|
24
24
|
- - ">="
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: 6.0.0
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: railties
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '4'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '4'
|
27
41
|
description: ''
|
28
42
|
email:
|
29
43
|
- aviemet@gmail.com
|
@@ -34,7 +48,6 @@ files:
|
|
34
48
|
- MIT-LICENSE
|
35
49
|
- README.md
|
36
50
|
- Rakefile
|
37
|
-
- lib/generators/generate_generator.rb
|
38
51
|
- lib/generators/install_generator.rb
|
39
52
|
- lib/generators/templates/ts_schema.rb
|
40
53
|
- lib/tasks/ts_schema_tasks.rake
|
@@ -50,7 +63,7 @@ licenses:
|
|
50
63
|
metadata:
|
51
64
|
homepage_uri: https://github.com/aviemet
|
52
65
|
source_code_uri: https://github.com/aviemet/ts_schema
|
53
|
-
post_install_message:
|
66
|
+
post_install_message:
|
54
67
|
rdoc_options: []
|
55
68
|
require_paths:
|
56
69
|
- lib
|
@@ -66,7 +79,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
66
79
|
version: '0'
|
67
80
|
requirements: []
|
68
81
|
rubygems_version: 3.2.32
|
69
|
-
signing_key:
|
82
|
+
signing_key:
|
70
83
|
specification_version: 4
|
71
84
|
summary: Generates typescript definitions from ActiveRecord
|
72
85
|
test_files: []
|
@@ -1,17 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'rails/generators'
|
4
|
-
require 'rails/generators/base'
|
5
|
-
|
6
|
-
module TsSchema
|
7
|
-
module Generators
|
8
|
-
class GenerateGenerator < Rails::Generators::Base
|
9
|
-
|
10
|
-
desc "Generates a schema.d.ts file"
|
11
|
-
|
12
|
-
def generate_schema
|
13
|
-
create_file TsSchema.configuration.output, TsSchema.generate
|
14
|
-
end
|
15
|
-
end
|
16
|
-
end
|
17
|
-
end
|