ts_schema 0.1.9 → 0.1.12

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: 98fda5d599b1c67632f071da87640ec19167fbc90c0ef50f3090ef1deb19a394
4
- data.tar.gz: 43145f323d86ce2acca7cf45687e0ac7b35e38e2fa0b5216f180fd920e7bd08f
3
+ metadata.gz: 8602c4a7ca10962ac35fd7c64a18d0669ed3f7d1ecdfdf7bc9c29a258bff754a
4
+ data.tar.gz: 322d779a986f2edf18d53829a6a8669326732be7aa4080567d2f4a1ecb1ebac0
5
5
  SHA512:
6
- metadata.gz: 20d2257583b6fd2c219ba6740822d7e7b05df7a49e165b9d8dd7d370a326e33cdf21f4c5920afea1fd76ffd428b5f6796ed2d7dfd0e484a7ea6f37e9248298f5
7
- data.tar.gz: e7640bf87f7bd2243a1bab5d3b5bc15188f5151f95236357571141ceef72f4ac95ed8e5fc2a79ac3aa90da4256b7d401ceedd48ebb89188650929031177da301
6
+ metadata.gz: 88fd048bbffe0eb93ac910bdcaf456a35e4ded1bf934dab9330d5ad1dba4d57ad3106c07a549a92555f312fe4d713d1b1b4b8c7d29d3909d85a7062df96e6426
7
+ data.tar.gz: 4c778296ba8de708bf9539bdcd163d79370c0477600d2bdbfd98a0e5c0355d3e02872728452be964922032cc880b3ac92ee270f40269e251734fb48ebfb74bcb
data/Rakefile CHANGED
@@ -1,2 +1,3 @@
1
1
  require "bundler/setup"
2
2
  require "bundler/gem_tasks"
3
+ require "ts_schema"
@@ -1,57 +1,89 @@
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
- # Options: camel|snake|pascal
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
- # Whether to generate the schema file on migrations and rollbacks
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
- # Whether to generate types for associations
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
- # Namespace
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
+ # Namespace for generated types
72
+ #
50
73
  # config.namespace = :schema
51
74
 
52
- # Options: tab|space
75
+
76
+ # Output schema as types or interfaces: type|interface
77
+ #
78
+ # config.schema_type = :interface
79
+
80
+
81
+ # Indentation options: tab|space
82
+ #
53
83
  # config.indent = :tab
54
84
 
85
+
55
86
  # If indent is spaces, specify how many
87
+ #
56
88
  # config.spaces = 2
57
89
  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 :generate do
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: :environment do
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 rollback: :environment do
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
@@ -11,8 +11,10 @@ module TsSchema
11
11
  default_type: :string,
12
12
  include_associated: true,
13
13
  namespace: :schema,
14
+ schema_type: :interface,
14
15
  indent: :tab,
15
16
  spaces: 2,
17
+ parent_classes: ["ApplicationRecord"],
16
18
  additional_models: []
17
19
  }
18
20
 
@@ -37,6 +39,5 @@ module TsSchema
37
39
  end
38
40
  self
39
41
  end
40
-
41
42
  end
42
43
  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
@@ -1,4 +1,7 @@
1
+ require "rails"
2
+
1
3
  module TsSchema
2
4
  class Railtie < ::Rails::Railtie
5
+ load "tasks/ts_schema_tasks.rake"
3
6
  end
4
7
  end
@@ -2,56 +2,74 @@ require 'fileutils'
2
2
 
3
3
  module TsSchema
4
4
  class SchemaGenerator
5
- def initialize
6
- Rails.application.eager_load!
7
- @models = ApplicationRecord.send(:subclasses)
8
- @models.concat(TsSchema.configuration.additional_models) unless TsSchema.configuration.additional_models.empty?
9
- @types = TsSchema.configuration.types.merge(TsSchema.configuration.custom_types || {})
10
- end
11
-
12
- def generate
13
- generate_typescript
14
- end
15
-
16
- def output_file
17
- path = TsSchema.configuration.output
18
- FileUtils.mkdir_p(File.dirname(path))
5
+ attr_accessor :config
6
+ attr_accessor :models
19
7
 
20
- content = generate
21
- return if File.exist?(path) && File.read(path) == content
8
+ def initialize(config = nil)
9
+ @config = config || TsSchema::Configuration.new
10
+ @models = []
22
11
 
23
- File.open(path, 'w') do |f|
24
- f.write content
12
+ Rails.application.eager_load!
13
+ @config.parent_classes.each do |parent|
14
+ @models.concat(get_subclasses(parent.to_s.constantize))
15
+ end
16
+ unless @config.additional_models.empty?
17
+ @models.concat(@config.additional_models.map do |m|
18
+ m.to_s.constantize
19
+ end)
25
20
  end
21
+ @types = @config.types.stringify_keys.merge(@config.custom_types.stringify_keys || {})
26
22
  end
27
23
 
28
- private
24
+ def get_subclasses(model)
25
+ models = model.send(:subclasses)
26
+ unless nested_empty?(models)
27
+ models.concat(models.flat_map do |m|
28
+ get_subclasses(m)
29
+ end)
30
+ end
31
+ models
32
+ end
29
33
 
30
- def generate_typescript
34
+ def generate
31
35
  type_template = ""
36
+
32
37
  @models.each do |model|
33
38
  columns = map_column_types(model)
34
- columns.concat(map_associations(model)) if TsSchema.configuration.include_associated
39
+ columns.concat(map_associations(model)) if @config.include_associated
35
40
 
36
41
  type_template += <<~TYPESCRIPT
37
- interface #{model.model_name.param_key.camelize} {
42
+ #{@config.schema_type} #{model.model_name.param_key.camelize} #{@config.schema_type.to_sym == :type ? "= " : ""}{
38
43
  #{columns.map { |column| "#{indent_as_str}#{column_name_cased(column[:name])}: #{column[:ts_type]};" }.join("\n")}
39
44
  }\n
40
45
  TYPESCRIPT
41
46
  end
47
+
42
48
  type_template = <<~TPL
43
- declare namespace #{TsSchema.configuration.namespace} {
49
+ declare namespace #{@config.namespace} {
44
50
  #{indent_wrapper(type_template)}
45
51
  }
46
52
  TPL
47
53
  end
48
54
 
55
+ def output_file
56
+ path = @config.output
57
+ FileUtils.mkdir_p(File.dirname(path))
58
+
59
+ content = generate
60
+ return if File.exist?(path) && File.read(path) == content
61
+
62
+ File.open(path, 'w') do |f|
63
+ f.write content
64
+ end
65
+ end
66
+
49
67
  def map_column_types(model)
50
68
  model.columns.map { |i|
51
- type = @types[i.type.to_s] || TsSchema.configuration.default_type
69
+ type = @types[i.type.to_s] || @config.default_type
52
70
 
53
71
  if(enum = model.defined_enums[i.name])
54
- type = enum.keys.map { |k| "'#{k}'" }.join(" | ")
72
+ type = enum.keys.map { |k| "'#{k}'" }.join("|")
55
73
  end
56
74
 
57
75
  {
@@ -78,8 +96,14 @@ module TsSchema
78
96
  end
79
97
  end
80
98
 
99
+ private
100
+
101
+ def nested_empty?(arr)
102
+ arr.is_a?(Array) && arr.flatten.empty?
103
+ end
104
+
81
105
  def column_name_cased(name)
82
- case TsSchema.configuration.case.to_sym
106
+ case @config.case.to_sym
83
107
  when :camel
84
108
  name.camelize(:lower)
85
109
  when :pascal
@@ -90,18 +114,18 @@ module TsSchema
90
114
  end
91
115
 
92
116
  def indent_as_str
93
- case TsSchema.configuration.indent.to_sym
117
+ case @config.indent.to_sym
94
118
  when :space || :spaces
95
- "".rjust(TsSchema.configuration.spaces, " ")
119
+ "".rjust(@config.spaces, " ")
96
120
  else
97
121
  "\t"
98
122
  end
99
123
  end
100
124
 
101
125
  def indent_wrapper(str)
102
- case TsSchema.configuration.indent.to_sym
126
+ case @config.indent.to_sym
103
127
  when :space || :spaces
104
- str.indent(TsSchema.configuration.spaces)
128
+ str.indent(@config.spaces)
105
129
  else
106
130
  str.indent(1, "\t")
107
131
  end
@@ -1,3 +1,3 @@
1
1
  module TsSchema
2
- VERSION = "0.1.9"
2
+ VERSION = "0.1.12"
3
3
  end
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,11 +16,19 @@ module TsSchema
15
16
  end
16
17
 
17
18
  def generate
18
- SchemaGenerator.new.generate
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
- SchemaGenerator.new.output_file
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
metadata CHANGED
@@ -1,17 +1,17 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ts_schema
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.9
4
+ version: 0.1.12
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-04-04 00:00:00.000000000 Z
11
+ date: 2022-04-06 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
- name: railties
14
+ name: rails
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
17
  - - ">="
@@ -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
@@ -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