orthoses-rails 1.1.0 → 1.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/generators/orthoses/rails/templates/rails.rake +7 -0
- data/lib/orthoses/active_model/attributes.rb +55 -0
- data/lib/orthoses/active_model.rb +1 -0
- data/lib/orthoses/active_record/belongs_to.rb +1 -9
- data/lib/orthoses/active_record/enum.rb +23 -3
- data/lib/orthoses/active_record/has_many.rb +1 -10
- data/lib/orthoses/active_record/has_one.rb +1 -10
- data/lib/orthoses/active_record/relation.rb +9 -0
- data/lib/orthoses/active_record.rb +11 -0
- data/lib/orthoses/rails/application.rb +1 -0
- data/lib/orthoses/rails/version.rb +1 -1
- metadata +5 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: dc7b416eba2452375317a5c028aeae285d135ee8c8ef4129f28170f46d0090d9
|
4
|
+
data.tar.gz: 71148b9456d3038c6960611ac78e764590f8becd9376e1d136fb06549e80a378
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6abe5dd4e76632c6039a20da11e44e63851713a4793e31661e246ce00d1de36ced9c0ecfe182efe2108df2e59c54e00cadf4d857eb1e7c447dd36d289de068b5
|
7
|
+
data.tar.gz: 6e1df2008c803ffa594d2fc96312ef9d97bda0570339604a40b47e8ff35c94118dd7ed2ca1cf77f7316cf3464ba7cbdc9ec438d182a4099983c0625ece69024c
|
@@ -17,6 +17,13 @@ namespace :orthoses do
|
|
17
17
|
# Complement missing const name.
|
18
18
|
use Orthoses::MissingName
|
19
19
|
|
20
|
+
# You can use other publicly available middleware.
|
21
|
+
# `Orthoses::YARD` is available at https://github.com/ksss/orthoses-yard.
|
22
|
+
# By using this middleware, you can add the capability
|
23
|
+
# to generate type information from YARD documentation.
|
24
|
+
# use Orthoses::YARD,
|
25
|
+
# parse: ['{app/lib}/**/*.rb']
|
26
|
+
|
20
27
|
# You can load hand written RBS.
|
21
28
|
# use Orthoses::LoadRBS,
|
22
29
|
# paths: Dir.glob(Rails.root / "sig/hand-written/**/*.rbs")
|
@@ -0,0 +1,55 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Orthoses
|
4
|
+
module ActiveModel
|
5
|
+
# < 7.0
|
6
|
+
# def attribute(name, type = Type::Value.new, **options)
|
7
|
+
# >= 7.0
|
8
|
+
# def attribute(name, cast_type = nil, default: NO_DEFAULT_PROVIDED, **options)
|
9
|
+
class Attributes
|
10
|
+
DEFAULT_TYPES = {
|
11
|
+
big_integer: '::Integer',
|
12
|
+
binary: '::String',
|
13
|
+
boolean: 'bool',
|
14
|
+
date: '::Date',
|
15
|
+
datetime: '::Time',
|
16
|
+
decimal: '::BigDecimal',
|
17
|
+
float: '::Float',
|
18
|
+
immutable_string: '::String',
|
19
|
+
integer: '::Integer',
|
20
|
+
string: '::String',
|
21
|
+
time: '::Time'
|
22
|
+
}
|
23
|
+
|
24
|
+
def initialize(loader)
|
25
|
+
@loader = loader
|
26
|
+
end
|
27
|
+
|
28
|
+
def call
|
29
|
+
attribute = CallTracer::Lazy.new
|
30
|
+
store = attribute.trace('ActiveModel::Attributes::ClassMethods#attribute') do
|
31
|
+
@loader.call
|
32
|
+
end
|
33
|
+
attribute.captures.each do |capture|
|
34
|
+
receiver_name = Utils.module_name(capture.method.receiver) or next
|
35
|
+
name = capture.argument[:name]
|
36
|
+
cast_type = capture.argument[:cast_type] || capture.argument[:type]
|
37
|
+
|
38
|
+
return_type = DEFAULT_TYPES[cast_type] || 'untyped'
|
39
|
+
|
40
|
+
generated_attribute_methods = "#{receiver_name}::ActiveModelGeneratedAttributeMethods"
|
41
|
+
c = store[generated_attribute_methods]
|
42
|
+
c.header = "module #{generated_attribute_methods}"
|
43
|
+
c << "def #{name}: () -> #{return_type}?"
|
44
|
+
c << "def #{name}=: (untyped) -> untyped"
|
45
|
+
|
46
|
+
unless store[receiver_name].body.include?("include #{generated_attribute_methods}")
|
47
|
+
store[receiver_name] << "include #{generated_attribute_methods}"
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
store
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
@@ -18,15 +18,7 @@ module Orthoses
|
|
18
18
|
type = if ref.polymorphic?
|
19
19
|
'untyped'
|
20
20
|
else
|
21
|
-
|
22
|
-
Utils.module_name(ref.klass) or next
|
23
|
-
rescue NameError => e
|
24
|
-
while e
|
25
|
-
Orthoses.logger.warn(e.message)
|
26
|
-
e = e.cause
|
27
|
-
end
|
28
|
-
next
|
29
|
-
end
|
21
|
+
Orthoses::ActiveRecord.reflection_klass_name(ref) or next
|
30
22
|
end
|
31
23
|
opt = "#{type}?"
|
32
24
|
|
@@ -67,15 +67,35 @@ module Orthoses
|
|
67
67
|
|
68
68
|
return_type_param = Hash === values ? "[String, String]" : "[String, Integer]"
|
69
69
|
store[base_name] << "def self.#{name.pluralize}: () -> ActiveSupport::HashWithIndifferentAccess#{return_type_param}"
|
70
|
+
enum_methods_content = store["#{base_name}::ActiveRecord_Enum_EnumMethods"]
|
71
|
+
enum_methods_content.header = "module #{base_name}::ActiveRecord_Enum_EnumMethods"
|
70
72
|
|
71
|
-
pairs = values.respond_to?(:each_pair) ? values.each_pair : values.each_with_index
|
73
|
+
pairs = (values.respond_to?(:each_pair) ? values.each_pair : values.each_with_index).to_h
|
72
74
|
pairs.each do |label, value|
|
73
75
|
value_method_name = "#{prefix}#{label}#{suffix}"
|
74
|
-
enum_methods_content = store["#{base_name}::ActiveRecord_Enum_EnumMethods"]
|
75
|
-
enum_methods_content.header = "module #{base_name}::ActiveRecord_Enum_EnumMethods"
|
76
76
|
enum_methods_content << "def #{value_method_name}?: () -> bool"
|
77
77
|
enum_methods_content << "def #{value_method_name}!: () -> bool"
|
78
|
+
|
79
|
+
value_method_alias = "#{prefix}#{label.to_s.gsub(/[\W&&[:ascii:]]+/, "_")}#{suffix}"
|
80
|
+
if value_method_alias != value_method_name
|
81
|
+
enum_methods_content << "def #{value_method_alias}?: () -> bool"
|
82
|
+
enum_methods_content << "def #{value_method_alias}!: () -> bool"
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
# Expressing type casting.
|
87
|
+
store[base_name] << "def #{name}: () -> (#{pairs.keys.map { |k| "\"#{k}\"" }.join(" | ")})"
|
88
|
+
symbol_pattern = if pairs.keys.any? { |key| key.match?(/[^a-zA-Z_]/) }
|
89
|
+
"(Symbol) -> void"
|
90
|
+
else
|
91
|
+
"(#{pairs.keys.map{|key|key.to_sym.inspect}.join(" | ")}) -> void"
|
78
92
|
end
|
93
|
+
overloads = [
|
94
|
+
symbol_pattern,
|
95
|
+
"(#{pairs.keys.map{|key|key.to_s.inspect}.join(" | ")}) -> void",
|
96
|
+
"(#{pairs.values.map(&:inspect).join(" | ")}) -> void",
|
97
|
+
]
|
98
|
+
store[base_name] << "def #{name}=: #{overloads.join(" | ")}"
|
79
99
|
end
|
80
100
|
end
|
81
101
|
end
|
@@ -15,16 +15,7 @@ module Orthoses
|
|
15
15
|
|
16
16
|
lines = base.reflect_on_all_associations(:has_many).flat_map do |ref|
|
17
17
|
singular_name = ref.name.to_s.singularize
|
18
|
-
type =
|
19
|
-
begin
|
20
|
-
Utils.module_name(ref.klass)
|
21
|
-
rescue NameError => e
|
22
|
-
while e
|
23
|
-
Orthoses.logger.warn(e.message)
|
24
|
-
e = e.cause
|
25
|
-
end
|
26
|
-
next
|
27
|
-
end
|
18
|
+
type = Orthoses::ActiveRecord.reflection_klass_name(ref) or next
|
28
19
|
|
29
20
|
collection_proxy = "::#{type}::ActiveRecord_Associations_CollectionProxy"
|
30
21
|
[
|
@@ -14,16 +14,7 @@ module Orthoses
|
|
14
14
|
base_name = Utils.module_name(base) || next
|
15
15
|
|
16
16
|
lines = base.reflect_on_all_associations(:has_one).flat_map do |ref|
|
17
|
-
type =
|
18
|
-
begin
|
19
|
-
Utils.module_name(ref.klass) or next
|
20
|
-
rescue NameError => e
|
21
|
-
while e
|
22
|
-
Orthoses.logger.warn(e.message)
|
23
|
-
e = e.cause
|
24
|
-
end
|
25
|
-
next
|
26
|
-
end
|
17
|
+
type = Orthoses::ActiveRecord.reflection_klass_name(ref) or next
|
27
18
|
opt = "#{type}?"
|
28
19
|
|
29
20
|
[
|
@@ -19,7 +19,16 @@ module Orthoses
|
|
19
19
|
class_specific_proxy = "#{model_name}::ActiveRecord_Associations_CollectionProxy"
|
20
20
|
class_specific_generated_relation_methods = "#{model_name}::GeneratedRelationMethods"
|
21
21
|
|
22
|
+
# Expressing delegation.
|
22
23
|
store[class_specific_generated_relation_methods].tap do |c|
|
24
|
+
klass.singleton_methods(false).each do |singleton_method|
|
25
|
+
c << "def #{singleton_method}: (*untyped, **untyped) -> untyped"
|
26
|
+
end
|
27
|
+
(klass.singleton_class.included_modules - ::ActiveRecord::Relation.included_modules).each do |mod|
|
28
|
+
mname = Utils.module_name(mod) or next
|
29
|
+
store[mname].header = "module #{mname}"
|
30
|
+
c << "include #{mname}"
|
31
|
+
end
|
23
32
|
end
|
24
33
|
|
25
34
|
store[class_specific_relation].tap do |c|
|
@@ -43,5 +43,16 @@ module Orthoses
|
|
43
43
|
'untyped'
|
44
44
|
end
|
45
45
|
end
|
46
|
+
|
47
|
+
def self.reflection_klass_name(ref)
|
48
|
+
Utils.module_name(ref.klass)
|
49
|
+
rescue NameError, ArgumentError => e
|
50
|
+
while e
|
51
|
+
Orthoses.logger.warn(e.message)
|
52
|
+
e = e.cause
|
53
|
+
end
|
54
|
+
|
55
|
+
nil
|
56
|
+
end
|
46
57
|
end
|
47
58
|
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: 1.
|
4
|
+
version: 1.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- ksss
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-
|
11
|
+
date: 2023-09-21 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: orthoses
|
@@ -16,14 +16,14 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - ">="
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: '1.
|
19
|
+
version: '1.11'
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - ">="
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: '1.
|
26
|
+
version: '1.11'
|
27
27
|
description: Orthoses middleware collection for Ruby on Rails
|
28
28
|
email:
|
29
29
|
- co000ri@gmail.com
|
@@ -38,6 +38,7 @@ files:
|
|
38
38
|
- lib/generators/orthoses/rails/templates/rails.rake
|
39
39
|
- lib/orthoses-rails.rb
|
40
40
|
- lib/orthoses/active_model.rb
|
41
|
+
- lib/orthoses/active_model/attributes.rb
|
41
42
|
- lib/orthoses/active_model/has_secure_password.rb
|
42
43
|
- lib/orthoses/active_record.rb
|
43
44
|
- lib/orthoses/active_record/belongs_to.rb
|