orthoses-rails 0.5.0 → 0.6.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: bf5adf50ae35b548291c69ba03b7eb6086e1214c863b83c85de0af3c81de3b17
4
- data.tar.gz: a162e4dc8583a4a738ac38b41ee7fb65db67349e08b2ead5f8bfc41bc3b057c1
3
+ metadata.gz: 46bcd93481527f23bfe512d336313721f7cf17fe67bb124e51e016f59cff14c2
4
+ data.tar.gz: 7a783be26aeeb877069e4c0e431765e274bb07dd25438669ca8dbb58c6417405
5
5
  SHA512:
6
- metadata.gz: 8c5494faf887bb600e081967321ec6c25e24610206de9014323f13e6b43147711eb05fd1d670f815adca2739f8f80988823a5c7b06adcc193092144b7aafb0d3
7
- data.tar.gz: 119911fd1cd01d7fc059fc3c23f989573771126a5ca4aa4a7091a7ca604a0a6d5d86726eda48312969695a30ec70498dd2af060231abca09aecb56212cfa2b68
6
+ metadata.gz: ef3237aa508e90177b76dd160456404cf37dfcd1907b18ad299b1cd2f95e1abd4971762de5a0679850943b220348b7f7528689eef31be84651a30cbb29eb2601
7
+ data.tar.gz: 353ee63dc4a5bd7fa82fa59f571766b842690c09bd98d14e4f3f1defbb77ec14870f361149b3ac0ab6b46cad9b933f02ecaf8190a5824a4e3739b088ba14bea4
data/README.md CHANGED
@@ -5,42 +5,36 @@ Orthoses::Rails automatically generates RBS for methods added by Rails.
5
5
 
6
6
  ## Features
7
7
 
8
- ### Orthoses::ActiveModel::HasSecurePassword
9
-
10
- Add signatures that generated form `ActiveModel::SecurePassword::ClassMethods#has_secure_password`.
11
-
12
- ### Orthoses::ActiveRecord::BelongsTo
13
-
14
- Add signatures that generated form `ActiveRecord::Associations::ClassMethods#belongs_to`.
15
-
16
- ### Orthoses::ActiveRecord::GeneratedAttributeMethods
17
-
18
- Add signatures that generated from DB schema columns.
19
-
20
- ### Orthoses::ActiveRecord::HasMany
21
-
22
- Add signatures that generated form `ActiveRecord::Associations::ClassMethods#has_many`.
23
-
24
- ### Orthoses::ActiveRecord::HasOne
25
-
26
- Add signatures that generated form `ActiveRecord::Associations::ClassMethods#has_one`.
27
-
28
- ### Orthoses::ActiveSupport::ClassAttribute
29
-
30
- Add signatures that generated form `Class#class_attribute`.
31
-
32
- ### Orthoses::ActiveSupport::Concern
33
-
34
- Add signature `extend ActiveSupport::Concern` only.
35
-
36
- ### Orthoses::ActiveSupport::MattrAccessor
37
-
38
- Add signatures that generated form `Module#mattr_accessor`, `Module#mattr_reader` and `Module#mattr_writer`.
39
-
40
- ### Orthoses::ActiveSupport::TimeWithZone
41
-
42
- Add signatures `Time` and `ActiveSupport::TimeWithZone`.
43
- Methods and mixin delegated from `Time` are added to `ActiveSupport::TimeWithZone`.
8
+ ### Orthoses::ActiveModel
9
+
10
+ - `HasSecurePassword`
11
+ - Add signatures that generated form `has_secure_password`.
12
+
13
+ ### Orthoses::ActiveRecord
14
+
15
+ - `BelongsTo`
16
+ - Add signatures that generated form `belongs_to`.
17
+ - `DelegatedType`
18
+ - Add signatures that generated from `delegated_type`
19
+ - `Enum`
20
+ - Add signatures that generated from `enum`
21
+ - `HasMany`
22
+ - Add signatures that generated form `has_many`.
23
+ - `HasOne`
24
+ - Add signatures that generated form `has_one`.
25
+ - `Scope`
26
+ - Add signatures that generated form `scope`.
27
+
28
+ ### Orthoses::ActiveSupport
29
+
30
+ - `ClassAttribute`
31
+ - Add signatures that generated form `class_attribute`.
32
+ - `Configurable`
33
+ - Add signatures that generated from `config_accessor`
34
+ - `Delegation`
35
+ - Add signatures that generated from `delegate`. The type definition of the method or instance variable specified by `to` is required.
36
+ - `MattrAccessor`
37
+ - Add signatures that generated form `mattr_accessor`, `cattr_accessor`, `mattr_reader`, `cattr_reader`, `mattr_writer` and `cattr_writer`.
44
38
 
45
39
  ## Installation
46
40
 
@@ -68,16 +62,14 @@ Orthoses::Builder.new do
68
62
  use YourCustom::Middleware
69
63
  use Orthoses::ActiveModel::HasSecurePassword
70
64
  use Orthoses::ActiveRecord::BelongsTo
71
- use Orthoses::ActiveRecord::GeneratedAttributeMethods
72
65
  use Orthoses::ActiveRecord::HasMany
73
66
  use Orthoses::ActiveRecord::HasOne
74
- use Orthoses::ActiveSupport::Concern
75
67
  use Orthoses::ActiveSupport::ClassAttribute
76
68
  use Orthoses::ActiveSupport::MattrAccessor
77
- use Orthoses::ActiveSupport::TimeWithZone
78
69
  use Orthoses::Mixin
79
70
  use Orthoses::Constant, strict: false
80
71
  use Orthoses::ObjectSpaceAll
72
+ use Orthoses::Autoload
81
73
  run -> () {
82
74
  Rake::Task[:environment].invoke
83
75
  Rails.application.eager_load!
@@ -0,0 +1,50 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Orthoses
4
+ module ActiveRecord
5
+ # <= 6.0
6
+ # not implemented
7
+ # >= 6.1
8
+ # def delegated_type(role, types:, **options)
9
+ class DelegatedType
10
+ def initialize(loader)
11
+ @loader = loader
12
+ end
13
+
14
+ def call
15
+ target = begin
16
+ ::ActiveRecord::DelegatedType.instance_method(:delegated_type)
17
+ rescue NameError
18
+ Orthoses.logger.warn("[ActiveRecord::DelegatedType] Skip since `delegated_type' is not implemented")
19
+ return @loader.call
20
+ end
21
+ delegated_type = CallTracer.new
22
+ store = delegated_type.trace(target) do
23
+ @loader.call
24
+ end
25
+
26
+ delegated_type.captures.each do |capture|
27
+ base_name = Utils.module_name(capture.method.receiver) or next
28
+ role = capture.argument[:role]
29
+ types = capture.argument[:types]
30
+ options = capture.argument[:options]
31
+ primary_key = options[:primary_key] || "id"
32
+
33
+ content = store[base_name]
34
+ content << "def #{role}_class: () -> (#{types.join(' | ')})"
35
+ content << "def #{role}_name: () -> String"
36
+ content << "def build_#{role}: () -> (#{types.join(' | ')})"
37
+ types.each do |type|
38
+ scope_name = type.tableize.gsub("/", "_")
39
+ singular = scope_name.singularize
40
+ content << "def #{singular}?: () -> bool"
41
+ content << "def #{singular}: () -> #{type}?"
42
+ content << "def #{singular}_#{primary_key}: () -> Integer?"
43
+ end
44
+ end
45
+
46
+ store
47
+ end
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,77 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Orthoses
4
+ module ActiveRecord
5
+ # <= 6.1
6
+ # def enum(definitions)
7
+ # >= 7.0
8
+ # def enum(name = nil, values = nil, **options)
9
+ class Enum
10
+ def initialize(loader)
11
+ @loader = loader
12
+ end
13
+
14
+ def call
15
+ enum = CallTracer.new
16
+ store = enum.trace(::ActiveRecord::Enum.instance_method(:enum)) do
17
+ @loader.call
18
+ end
19
+
20
+ enum.captures.each do |capture|
21
+ base_name = Utils.module_name(capture.method.receiver) or next
22
+
23
+ if capture.argument[:definitions]
24
+ # on rails 6
25
+ definitions = capture.argument[:definitions].slice!(:_prefix, :_suffix, :_scopes, :_default)
26
+ options = capture.argument[:definitions].transform_keys { |key| :"#{key[1..-1]}" }
27
+ definitions.each { |name, values| _enum(store, base_name, name, values, **options) }
28
+ else
29
+ # on rails 7
30
+ name = capture.argument[:name]
31
+ values = capture.argument[:values]
32
+ options = capture.argument[:options]
33
+ if name
34
+ # rails 7 style
35
+ values, options = options, {} unless values
36
+ _enum(store, base_name, name, values, **options)
37
+ else
38
+ # rails 6 style
39
+ definitions = options.slice!(:_prefix, :_suffix, :_scopes, :_default)
40
+ options.transform_keys! { |key| :"#{key[1..-1]}" }
41
+
42
+ definitions.each { |name, values| _enum(store, base_name, name, values, **options) }
43
+ end
44
+ end
45
+ end
46
+
47
+ store
48
+ end
49
+
50
+ private
51
+
52
+ def _enum(store, base_name, name, values, prefix: nil, suffix: nil, **_options)
53
+ name = name.to_s
54
+
55
+ prefix = if prefix
56
+ prefix == true ? "#{name}_" : "#{prefix}_"
57
+ end
58
+
59
+ suffix = if suffix
60
+ suffix == true ? "_#{name}" : "_#{suffix}"
61
+ end
62
+
63
+ return_type_param = Hash === values ? "[String, String]" : "[String, Integer]"
64
+ store[base_name] << "def self.#{name.pluralize}: () -> ActiveSupport::HashWithIndifferentAccess#{return_type_param}"
65
+
66
+ pairs = values.respond_to?(:each_pair) ? values.each_pair : values.each_with_index
67
+ pairs.each do |label, value|
68
+ value_method_name = "#{prefix}#{label}#{suffix}"
69
+ enum_methods_content = store["#{base_name}::ActiveRecord_Enum_EnumMethods"]
70
+ enum_methods_content.header = "module #{base_name}::ActiveRecord_Enum_EnumMethods"
71
+ enum_methods_content << "def #{value_method_name}?: () -> bool"
72
+ enum_methods_content << "def #{value_method_name}!: () -> bool"
73
+ end
74
+ end
75
+ end
76
+ end
77
+ end
@@ -0,0 +1,63 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Orthoses
4
+ module ActiveRecord
5
+ # def scope(name, body, &block)
6
+ class Scope
7
+ def initialize(loader)
8
+ @loader = loader
9
+ end
10
+
11
+ def call
12
+ scope = CallTracer.new
13
+ store = scope.trace(::ActiveRecord::Scoping::Named::ClassMethods.instance_method(:scope)) do
14
+ @loader.call
15
+ end
16
+
17
+ scope.captures.each do |capture|
18
+ base_name = Utils.module_name(capture.method.receiver) or next
19
+
20
+ name = capture.argument[:name]
21
+ body = capture.argument[:body]
22
+
23
+ definition = "#{name}: #{parameters_to_type(body.parameters)} -> #{base_name}::ActiveRecord_Relation"
24
+ store[base_name] << "def self.#{definition}"
25
+ store["#{base_name}::GeneratedRelationMethods"].header = "module #{base_name}::GeneratedRelationMethods"
26
+ store["#{base_name}::GeneratedRelationMethods"] << "def #{definition}"
27
+ end
28
+
29
+ store
30
+ end
31
+
32
+ private
33
+
34
+ def parameters_to_type(parameters)
35
+ # @type var res: Array[String]
36
+ res = []
37
+ # @type var block: String?
38
+ block = nil
39
+ parameters.each do |(type, name)|
40
+ case type
41
+ when :req
42
+ res << "untyped #{name}"
43
+ when :opt
44
+ res << "?untyped #{name}"
45
+ when :keyreq
46
+ res << "#{name}: untyped"
47
+ when :key
48
+ res << "?#{name}: untyped"
49
+ when :rest
50
+ res << "*untyped #{name}"
51
+ when :keyrest
52
+ res << "**untyped #{name}"
53
+ when :block
54
+ block = " { (*untyped) -> untyped }"
55
+ else
56
+ raise "unexpected: #{type}"
57
+ end
58
+ end
59
+ "(#{res.join(", ")})#{block}"
60
+ end
61
+ end
62
+ end
63
+ end
@@ -1,7 +1,10 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require_relative 'active_record/belongs_to'
4
+ require_relative 'active_record/delegated_type'
5
+ require_relative 'active_record/enum'
4
6
  require_relative 'active_record/generated_attribute_methods'
5
7
  require_relative 'active_record/has_many'
6
8
  require_relative 'active_record/has_one'
7
9
  require_relative 'active_record/query_methods'
10
+ require_relative 'active_record/scope'
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Orthoses
4
4
  module Rails
5
- VERSION = "0.5.0"
5
+ VERSION = "0.6.0"
6
6
  end
7
7
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: orthoses-rails
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.0
4
+ version: 0.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - ksss
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2022-06-26 00:00:00.000000000 Z
11
+ date: 2022-07-01 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: orthoses
@@ -53,10 +53,13 @@ files:
53
53
  - lib/orthoses/active_model/has_secure_password.rb
54
54
  - lib/orthoses/active_record.rb
55
55
  - lib/orthoses/active_record/belongs_to.rb
56
+ - lib/orthoses/active_record/delegated_type.rb
57
+ - lib/orthoses/active_record/enum.rb
56
58
  - lib/orthoses/active_record/generated_attribute_methods.rb
57
59
  - lib/orthoses/active_record/has_many.rb
58
60
  - lib/orthoses/active_record/has_one.rb
59
61
  - lib/orthoses/active_record/query_methods.rb
62
+ - lib/orthoses/active_record/scope.rb
60
63
  - lib/orthoses/active_support.rb
61
64
  - lib/orthoses/active_support/class_attribute.rb
62
65
  - lib/orthoses/active_support/configurable.rb