ts_schema 0.1.12 → 0.2.1
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/README.md +45 -3
- data/lib/generators/templates/ts_schema.rb +44 -23
- data/lib/ts_schema/configuration.rb +8 -3
- data/lib/ts_schema/schema_generator.rb +33 -9
- data/lib/ts_schema/version.rb +1 -1
- data/lib/ts_schema.rb +0 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: cf11b26c1cf7b979dc749c5ed2a7cd5c6f580a1d93d715dc684a3dd11cdf0f1d
|
4
|
+
data.tar.gz: 671e245c29ff9511be5db1f83815bfe6553bccea06021eaabe86414e9f034fff
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 39fd032dd6b861491e69439e46ca7d0150455795f6c3c85e192d14720f2b9299471ec9c333f8dddeb6e41f3eeae2759e3b6beed2c989c4f51d805340277e14e5
|
7
|
+
data.tar.gz: 938c2fd5b9bc1320e56a5db9444a644473909f876de0c9561d04af0245c2b91e2e9ec5f3feb4d1cd619d490e77317631334c3d458e76ec036080ebd6a736be36
|
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
|
|
@@ -26,9 +26,51 @@ You can manually generate the schema file by running:
|
|
26
26
|
rails ts_schema:generate
|
27
27
|
```
|
28
28
|
|
29
|
+
### Default type mappings
|
30
|
+
|
31
|
+
|Ruby Type|Typescript Type|
|
32
|
+
|:---|:---|
|
33
|
+
|string|string|
|
34
|
+
|text|string|
|
35
|
+
|integer|number|
|
36
|
+
|enum|number|
|
37
|
+
|bigint|number|
|
38
|
+
|float|number|
|
39
|
+
|decimal|number|
|
40
|
+
|json|Record<string, any>|
|
41
|
+
|jsonb|Record<string, any>|
|
42
|
+
|binary|string|
|
43
|
+
|boolean|boolean|
|
44
|
+
|date|string|
|
45
|
+
|datetime|string|
|
46
|
+
|timestamp|string|
|
47
|
+
|datetime_with_timezone|string|
|
48
|
+
|inet|string|
|
49
|
+
|cidr|string|
|
50
|
+
|macaddr|string|
|
51
|
+
|
52
|
+
### Initializer options
|
53
|
+
|
54
|
+
|Option|Default|Values|Description|
|
55
|
+
|---|---|---|---|
|
56
|
+
|case |`:camel`|`:camel`<br/>`:snake`<br/>`:pascal`|camelCase<br/>snake_case<br/>PascalCase|
|
57
|
+
|output |`Rails.root.join('app', 'assets', 'javascripts', 'schema.d.ts')`|Any path|Path to output generated file|
|
58
|
+
|auto_generate |`true`|`boolean`|Whether to automatically (re)generate the defenitions after running migrations|
|
59
|
+
|custom_types |`{}`|`{ ruby_type: 'typescriptType' }`|Use to add or override type mappings for any type|
|
60
|
+
|default_type |`:string`|Any typescript type|The default output type to use if a ruby type is not included in the type mappings|
|
61
|
+
|include_associated|`true`|`boolean`|Whether to include associated models as fields on the generated interfaces|
|
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
|
+
|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
|
+
|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
|
+
|namespace |`:schema`|string\|symbol|The typescript namespace to contain generated types|
|
66
|
+
|schema_type |`:interface`|`:interface`\|`:type`|Whether to generate typescript definitions as types or interfaces. Interfaces are recommended since they are easier to extend|
|
67
|
+
|indent|`:tab`|`:tab`\|`:space`|Indentation using tabs or spaces|
|
68
|
+
|spaces|`2`|number|Number of spaces for indentation if indentation is set to spaces|
|
69
|
+
|
70
|
+
|
29
71
|
## Gotchas
|
30
72
|
|
31
|
-
|
73
|
+
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
74
|
|
33
75
|
## License
|
34
76
|
|
@@ -1,26 +1,5 @@
|
|
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
|
-
|
22
1
|
TsSchema.setup do |config|
|
23
|
-
# Case options: camel|snake|pascal
|
2
|
+
# Case options for field names: camel|snake|pascal
|
24
3
|
#
|
25
4
|
# config.case = :camel
|
26
5
|
|
@@ -35,7 +14,27 @@ TsSchema.setup do |config|
|
|
35
14
|
# config.auto_generate = true
|
36
15
|
|
37
16
|
|
38
|
-
# Add custom type mappings or overrides
|
17
|
+
# Add custom type mappings or overrides (as strings or symbols)
|
18
|
+
#
|
19
|
+
# Default type mappings:
|
20
|
+
# string: string
|
21
|
+
# text: string
|
22
|
+
# integer: number
|
23
|
+
# enum: number
|
24
|
+
# bigint: number
|
25
|
+
# float: number
|
26
|
+
# decimal: number
|
27
|
+
# json: Record<string, any>
|
28
|
+
# jsonb: Record<string, any>
|
29
|
+
# binary: string
|
30
|
+
# boolean: boolean
|
31
|
+
# date: string
|
32
|
+
# datetime: string
|
33
|
+
# timestamp: string
|
34
|
+
# datetime_with_timezone: string
|
35
|
+
# inet: string
|
36
|
+
# cidr: string
|
37
|
+
# macaddr: string
|
39
38
|
#
|
40
39
|
# config.custom_types = {
|
41
40
|
#
|
@@ -68,6 +67,28 @@ TsSchema.setup do |config|
|
|
68
67
|
# ]
|
69
68
|
|
70
69
|
|
70
|
+
# Ignore certain fields, omitting them from the generated schema: :optional|(string)|false
|
71
|
+
# Key is the name of the field to override options for.
|
72
|
+
#
|
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 password as an optional field will append a ? to password
|
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
|
+
# Override types for fields by field name. This is globally applied.
|
84
|
+
# Useful for polymorphic associations which would otherwise be of type string, e.g.:
|
85
|
+
# commentable_type: "'Product'|'Review'"
|
86
|
+
|
87
|
+
# config.field_type_overrides: {
|
88
|
+
|
89
|
+
# }
|
90
|
+
|
91
|
+
|
71
92
|
# Namespace for generated types
|
72
93
|
#
|
73
94
|
# config.namespace = :schema
|
@@ -10,12 +10,17 @@ 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
|
+
},
|
19
|
+
field_type_overrides: {},
|
13
20
|
namespace: :schema,
|
14
|
-
|
21
|
+
schema_type: :interface,
|
15
22
|
indent: :tab,
|
16
23
|
spaces: 2,
|
17
|
-
parent_classes: ["ApplicationRecord"],
|
18
|
-
additional_models: []
|
19
24
|
}
|
20
25
|
|
21
26
|
attr_accessor(*DEFAULTS.keys)
|
@@ -7,6 +7,8 @@ module TsSchema
|
|
7
7
|
|
8
8
|
def initialize(config = nil)
|
9
9
|
@config = config || TsSchema::Configuration.new
|
10
|
+
@config.field_overrides = @config.field_overrides.stringify_keys
|
11
|
+
@config.field_type_overrides = @config.field_type_overrides.stringify_keys
|
10
12
|
@models = []
|
11
13
|
|
12
14
|
Rails.application.eager_load!
|
@@ -18,6 +20,8 @@ module TsSchema
|
|
18
20
|
m.to_s.constantize
|
19
21
|
end)
|
20
22
|
end
|
23
|
+
@models.sort_by! { |c| c.name }
|
24
|
+
|
21
25
|
@types = @config.types.stringify_keys.merge(@config.custom_types.stringify_keys || {})
|
22
26
|
end
|
23
27
|
|
@@ -33,7 +37,7 @@ module TsSchema
|
|
33
37
|
|
34
38
|
def generate
|
35
39
|
type_template = ""
|
36
|
-
|
40
|
+
|
37
41
|
@models.each do |model|
|
38
42
|
columns = map_column_types(model)
|
39
43
|
columns.concat(map_associations(model)) if @config.include_associated
|
@@ -65,18 +69,38 @@ module TsSchema
|
|
65
69
|
end
|
66
70
|
|
67
71
|
def map_column_types(model)
|
68
|
-
model.columns.map { |
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
+
model.columns.map { |column|
|
73
|
+
column_name = column.name.to_s
|
74
|
+
next if @config.field_overrides[column_name] == :omit
|
75
|
+
|
76
|
+
type_override = config.field_type_overrides[column_name]
|
77
|
+
|
78
|
+
type = type_override ? type_override : @types[column.type.to_s] || @config.default_type
|
79
|
+
name = map_name(column.name)
|
80
|
+
null = column.null
|
81
|
+
null = true if @config.field_overrides[name]&.to_s == "optional"
|
82
|
+
|
83
|
+
if(enum = model.defined_enums[name])
|
72
84
|
type = enum.keys.map { |k| "'#{k}'" }.join("|")
|
73
85
|
end
|
74
|
-
|
86
|
+
|
75
87
|
{
|
76
|
-
name: "#{
|
77
|
-
ts_type: "#{type}#{" | null" if
|
88
|
+
name: "#{name}#{"?" if null }",
|
89
|
+
ts_type: "#{type}#{" | null" if null}"
|
78
90
|
}
|
79
|
-
}
|
91
|
+
}.compact
|
92
|
+
end
|
93
|
+
|
94
|
+
def map_name(name)
|
95
|
+
final_name = name.to_s
|
96
|
+
return final_name unless @config.field_overrides[final_name]
|
97
|
+
|
98
|
+
if @config.field_overrides[final_name]&.to_s != "optional"
|
99
|
+
final_name = @config.field_overrides[final_name]&.to_s
|
100
|
+
|
101
|
+
final_name = map_name(final_name) if @config.field_overrides[final_name]
|
102
|
+
end
|
103
|
+
final_name
|
80
104
|
end
|
81
105
|
|
82
106
|
def map_associations(model)
|
data/lib/ts_schema/version.rb
CHANGED
data/lib/ts_schema.rb
CHANGED
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.2.1
|
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-
|
11
|
+
date: 2022-07-10 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|